Подтвердить что ты не робот

Solr Частичное и полное совпадение строк

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

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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

  • NGramFilterFactory
  • 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

  • Перейдите на панель инструментов Heroku для вашего приложения.
  • Перейдите на вкладку ресурсов, затем щелкните над надстройкой Websolr
  • Нажмите ссылку по умолчанию в разделе "Индексы"
  • Нажмите ссылку "Расширенная настройка"
  • Вставьте в свой schema.xml из своего локального файла, включая конфигурацию для вашего токенизатора Ngram (см. выше). Сохранить.
  • Скопируйте ссылку в поле "Настроить приложение Heroku", затем вставьте ее в терминал, чтобы установить ссылку WEBSOLR_URL в вашей конфигурации heroku.
  • Нажмите ссылку "Статус индекса", чтобы получить отличную статистику и посмотреть, работает ли вы быстро или медленно.
  • Reindex all

heroku run rake sunspot: reindex [5000]

  • Не используйте rak sunspot для запуска гелькону: solr: reindex - он устарел, не принимает никаких параметров и медленнее работает
  • Размер партии по умолчанию - 50, большинство людей предлагают использовать 1000, но я видел значительно более быстрые результаты (1000 строк в секунду, а не около 500 гц), нажимая его на 5000 +

Ответ 3

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

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" без swet.

Ответ 4

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

Попробуйте определить 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, если вы используете утилизацию)