Как повысить более длинные Ngram в Solr? - PullRequest
7 голосов
/ 15 ноября 2011

Я использую следующий фильтр в schema.xml:

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

Как я могу увеличить более длинные нграммы?Например, когда я ищу «bookpage», документ, содержащий «bookpage», должен быть оценен намного выше, чем документ с «book».

1 Ответ

5 голосов
/ 15 ноября 2011

Я не знаю способа динамического повышения в зависимости от длины термина (т. Е. С помощью оператора Function Query). Я подозреваю, что нет ни одного.

Тем не менее, я часто хочу аппроксимировать логику, которую вы ищете: долгосрочные совпадения заслуживают более высокого смыслового веса.

Чаще всего я буду индексировать текстовое значение в двух разных полях. Одним из них является минимально обработанное текстовое поле без нграмм. Другое похоже, но также обрабатывается с помощью ngrams.

Вот некоторые примеры выдержек из схемы, которую я использовал таким образом. Для поиска по этой схеме я бы сильно увеличил поле text по сравнению с text_ngram. Таким образом, любые совпадения с полем text могут сильно повлиять на релевантность, в то время как совпадения с text_ngram могут все еще собирать и релевантные результаты.

<?xml version="1.0" encoding="UTF-8"?>
<schema name="Sunspot Customized NZ" version="1.0">
  <types>

    <!--
      A text type with minimal text processing, for the greatest semantic
      value in a term match. Boost this field heavily.
    -->
    <fieldType name="text" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory" />
        <filter class="solr.StandardFilterFactory" />
        <filter class="solr.LowerCaseFilterFactory" />
      </analyzer>
    </fieldType>

    <!--
      Looser matches with NGram processing for substrings of terms and synonyms
    -->
    <fieldType name="text_ngram" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory" />
        <filter class="solr.StandardFilterFactory" />
        <filter class="solr.LowerCaseFilterFactory" />
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
        <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="6" side="front" />
      </analyzer>
    </fieldType>

    <!-- other stuff -->

  </types>
  <fields>

    <!-- id, other scalar values -->

    <!-- catch-all for the text and text_ngram types -->
    <field name="text"       stored="false" type="text"        multiValued="true"  indexed="true" />
    <field name="text_ngram" stored="false" type="text_ngram"  multiValued="true"  indexed="true" />

    <!-- various dynamicField definitions -->

    <!-- sample dynamicField definitions for text and text_ngram -->
    <dynamicField name="*_text"   type="text" indexed="true" stored="false" multiValued="false" />
    <dynamicField name="*_text_ngram"   type="text_ngram" indexed="true" stored="false" multiValued="false" />

  </fields>

  <!-- copy text fields into my text and text_ngram catch-all fields -->
  <copyField source="*_text"  dest="text" />
  <copyField source="*_text"  dest="text_ngram" />

</schema>

Это не совсем то, что вы ищете, но вы можете использовать аналогичный подход.

Например, создайте небольшую коллекцию промежуточных типов полей, обработанных NGram, скажем, длиной 1-3, 4-6, 7-9, и соответственно увеличьте их.

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