Поиск исключительных версий слова в Sunspot / Solr - PullRequest
0 голосов
/ 22 декабря 2011

У меня есть приложение Rails + Sunspot, и я работаю над его настройкой, чтобы поиск возвращал однослойную версию запроса.Например:

Я хочу, чтобы поиск "куки" возвращал что-то с именем "куки".В настоящее время мой поиск в Sunspot возвращает «cookies», но не «cookie» (singluar).

Я внес некоторые изменения в schema.xml в Solr, добавив solr.EdgeNGramFilterFactory для обеспечения большей гибкости, но EdgeNGramFilterFactory не подходит для этогослучай, поскольку он разрешает совпадения только тогда, когда запрос является подстрокой имени результата.Насколько я понимаю, EdgeNGramFilterFactory будет возвращать «cookie», когда пользователь ищет «co», «coo», «cook» или «cooki», но не суперструну «cookie» (то есть: куки).Проще говоря, это потому, что «cookie» не является подстрокой в ​​«cookie».

Я пытался добавить все три встроенных фабрики по производству стоек Solr, но безрезультатно.Вы можете увидеть один закомментированный в моей схеме.

В schema.xml соответствующее поле выглядит следующим образом:

<fieldType name="text" class="solr.TextField" omitNorms="false">
  <analyzer type="index">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    <filter class="solr.EdgeNGramFilterFactory" minGramSize="2" maxGramSize="15" side="front"/>
    <!-- <filter class="solr.EnglishMinimalStemFilterFactory"/> -->
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.StandardTokenizerFactory"/>
    <filter class="solr.StandardFilterFactory"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

Я предполагал, что мог бы сделать один запрос пользователя одним, но я бы не хотелдотроньтесь до их запроса, прежде чем он достигнет Solr.

Вы можете поиграть с этим здесь: http://staging.zisboombah.com/parent/food_guide/?search=cookie. Попробуйте изменить запрос между "cookie" и "cookies".

Любые советы о том, каксделать это в Solr будет очень признателен!

Ответы [ 2 ]

2 голосов
/ 22 декабря 2011

Опции solr xml упорядочены. Вы хотите, чтобы стеммер шел перед фильтром ngram, чтобы вы ngram-ize cooki вместо стебля c, co и т. Д.

Комбинирование фильтров таким способом может привести к некоторым странным результатам, в основном в зависимости от того, насколько агрессивен ваш стеммер. Вы обязательно должны добавить стеммер в анализатор запросов, но это будет мешать вашему автозаполнению.

Лучшее решение: используйте copyField для создания независимых полей text_stemmed и text_autocomplete. Затем выполните поиск с помощью запроса OR по обоим полям.

0 голосов
/ 03 января 2012

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

Вот мой пример:

schema.xml

<schema>
  <types>

    <fieldType name="text" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

    <fieldType name="text_en" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
    </fieldType>

    <fieldType name="text_stopwords" class="solr.TextField" omitNorms="false">
      <analyzer>
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StandardFilterFactory"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
      </analyzer>
    </fieldType>

    <!-- ... -->
  </types>
  <fields>
    <!-- ... -->
  </fields>

  <copyField source="*_text"   dest="text"/>
  <copyField source="*_texts"  dest="text"/>
  <copyField source="*_textsv" dest="text"/>
  <copyField source="*_textv"  dest="text"/>

</schema>

Моделирование солнечных пятен

Использование директивы copyField может сохранить некоторые настройки в модели.Однако Sunspot использует эти объявления text, чтобы решить, какие поля keywords -поиск по умолчанию, поэтому я хотел бы включить отдельные вызовы text, которые используют :as для указания полного имени поля документа Solr.

searchable do
  text :name, stored: true, default_boost: 10
  text :name, as: 'name_text_en'
  text :description, stored: true
end
...