Solr частичное и полное совпадение строк - PullRequest
22 голосов
/ 28 января 2011

Я пытаюсь разрешить поиск по частичным строкам в Solr, чтобы, если кто-то искал «ppopota», он получал такой же результат, как если бы он искал «hippopotamus».Я читаю документацию вверх и вниз и чувствую, что исчерпал свои возможности.Пока у меня есть следующее:

Определение нового типа поля:

<fieldtype name="testedgengrams" class="solr.TextField">
   <analyzer>
     <tokenizer class="solr.LowerCaseTokenizerFactory"/>
     <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
  </analyzer>
</fieldtype>

Определение поля типа "testgengrams":

<field name="text_ngrams" type="testedgengrams" indexed="true" stored="false"/>

Копирование содержимого text_ngramsв текст:

<copyField source="text_ngrams" dest="text"/>

Увы, это не работает.Чего мне не хватает?

Ответы [ 4 ]

17 голосов
/ 28 января 2011

Вы используете EdgeNGramFilterFactory , который генерирует токены 'hi', 'hip', 'hipp' и т. Д., Поэтому он не будет соответствовать 'ppopota'. Вместо этого используйте NGramFilterFactory.

11 голосов
/ 06 сентября 2013

Чтобы включить частичный поиск слова

Вы должны отредактировать локальный файл schema.xml, обычно в solr / config, чтобы добавить:

  1. NGramFilterFactory
  2. EdgeNGramFilterFactory

Вот как выглядит мой файл: пример solr schema.xml

Вот строка для вставки:

<filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>

EdgeNGram

Я пошел с опцией EdgeN. Он не позволяет осуществлять поиск по середине слов, но он позволяет частичный поиск по словам, начиная с начала слова. Это сокращает количество ложных срабатываний / совпадений, которые вам не нужны, работает лучше и обычно не пропускается пользователями. Также мне нравится minGramSize = 2, поэтому вы должны ввести минимум 2 символа. Некоторые люди устанавливают это на 3.

Как только ваш локальный настроен и работает, вы должны отредактировать schema.xml, используемый websolr, в противном случае вы получите поведение по умолчанию, которое требует ввода полного слова, даже если для ваших моделей настроен полнотекстовый поиск.

Возьмите его на следующий уровень

5 способов ускорить индексацию

Специальные инструкции для редактирования файла websolr schema.xml, если вы используете Heroku

  1. Перейдите на онлайн-панель Heroku для своего приложения
  2. Перейдите на вкладку ресурсов, затем нажмите на дополнение Websolr
  3. Нажмите ссылку по умолчанию под индексами
  4. Нажмите на ссылку Advanced Configuration
  5. Вставьте ваш файл schema.xml из вашего локального каталога, включая конфигурацию для выбранного вами токенайзера Ngram (упомянутого выше). Сохранить.
  6. Скопируйте ссылку в поле «Настройка приложения Heroku», затем вставьте ее в терминал, чтобы установить ссылку WEBSOLR_URL в конфигурации вашего heroku.
  7. Нажмите ссылку «Состояние индекса», чтобы получить отличную статистику и узнать, быстро или медленно вы бежите.
  8. Переиндексировать все

Герои бегут по граблям: переиндексация [5000]

  • Не используйте геройскую пробежку с граблями: solr: reindex - устарела, не принимает параметров и НАМНОГО медленнее
  • Размер пакета по умолчанию равен 50, большинство людей предлагают использовать 1000, но я видел значительно более быстрые результаты (1000 строк в секунду, а не около 500 об / с), увеличив его до 5000 +
9 голосов
/ 23 ноября 2011

Хорошо, я делаю то же самое с именем поля

name_de

И мне удалось заставить эту вещь работать, используя copyField, вот так:

schema.xml

<schema name="solr-magento" version="1.2">
    <types>
       ...
        <fieldType name="type_name_de_partial" class="solr.TextField">
            <analyzer type="index">
                <tokenizer class="solr.WhitespaceTokenizerFactory"/>
                <filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="1000" side="front" />
                <filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="1000" side="back" />
                <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true"/>
                <filter class="solr.LowerCaseFilterFactory"/>
                <filter class="solr.TrimFilterFactory" />
                <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
                <filter class="solr.SnowballPorterFilterFactory" language="German" protected="protwords_de.txt"/>
            </analyzer>
            <analyzer type="query">
                <tokenizer class="solr.StandardTokenizerFactory"/>
                <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
                <filter class="solr.LowerCaseFilterFactory"/>
                <filter class="solr.TrimFilterFactory" />
                <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
                <filter class="solr.SnowballPorterFilterFactory" language="German" protected="protwords_de.txt"/>
            </analyzer>
        </fieldType>
    </types>

    ...

    <fields>
        ...
        <field name="name_de_partial" type="type_name_de_partial" indexed="true" stored="true"/>
    </fields>

    ....

    <copyField source="name_de" dest="name_de_partial" />
</schema>

Затем создайте условие поиска в solrconfig.xml

<requestHandler name="magento_de" class="solr.SearchHandler">
    <lst name="defaults">
        <str name="defType">dismax</str>
        <str name="echoParams">explicit</str>
        <str name="tie">0.01</str>                                          <!-- Tie breaker -->
        <str name="qf">name_de_partial^1.0 name_de^3.0</str>                <!-- Phrase Fields -->
        <str name="pf">name_de_partial^1.0 name_de^3.0</str>                <!-- Phrase Fields -->
        <str name="mm">3&lt;90%</str>                                       <!-- Minimum 'Should' Match [id 1..3 must much all, else 90proc] -->
        <int name="ps">100</int>                                            <!-- Phrase Slop -->
        <str name="q.alt">*:*</str>
        ..
    </lst>
    <arr name="last-components">
        <str>spellcheck</str>
    </arr>
</requestHandler>

С помощью этого solr выполняется поиск в полях name_de_partial с pow 1.0 и в name_de с pow 3.0

Так что, если движок будет определенСлово запроса в name_de, затем оно помещается в начало списка.Если он также находит что-то в name_de_partial, то он также считает и помещает в результаты.

И поле name_de_partial использует специальные фильтры solr, поэтому оно может найти слово "hippie", используя запрос "hip" или "ppie" или "ippi "без удара.

5 голосов
/ 01 февраля 2011

Если вы установите EdgeNGramFilterFactory или NGramFilterFactory как во время индекса, так и во время запроса, в сочетании с q.op = AND (или по умолчанию mm = 100%, если вы используете dismax), у вас возникнут некоторые проблемы.

Попробуйте определить NGramFilterFactory только во время индекса:

<fieldType name="testedgengrams" class="solr.TextField">
    <analyzer type="index">
        <tokenizer class="solr.LowerCaseTokenizerFactory"/>
        <filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="15"/>
    </analyzer>
    <analyzer type="query">
        <tokenizer class="solr.LowerCaseTokenizerFactory"/>
    </analyzer>
</fieldType>

или попробуйте установить q.op = OR (или mm = 1, если вы используете dismax)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...