2014-01-11 1 views
2

Я использую Solr 4.6.0, и я пытаюсь получить наиболее частые термины, сгруппированные по году. Поскольку возможно, что мои стоп-слова могут часто меняться, я не применяю стоп-слова при индексировании времени. Вместо этого все динамические словарные списки, такие как стоп-слова, прообразы и синонимы, используются по адресу query времени. Но хотя в списке повторений есть такие термины, как «из» и «the», они все еще отображаются в списке результатов (см. Результаты).Solr facets игнорируют стоп-слова во время запроса

Вопрос: Как я могу получить граненые и стопслов фильтруются результаты, если я использую StopFilterFactory только во время запроса?

Дополнительная информация

Если я использую StopFilterFactory в индексации времени, все, как и ожидалось. Когда я запускаю свой запрос, параметры, такие как «из» и «они», отфильтровываются.

Я также проверил функциональные возможности fieldtype text_en с помощью инструмента анализа данных Solr и результаты ожидаются - «из» и «из» отфильтрованы. Это означает, что каким-то образом SearchHandler не позвонил анализатор?

Запрос

http://ip:port/solr/collection1/select?q=*:*&rows=0&facet=true&facet.pivot=year,text

Результаты

[..] 
<lst name="facet_pivot"> 
    <arr name="year,text"> 
    <lst> 
     <str name="field">year</str> 
     <int name="value">2009</int> 
     <int name="count">139</int> 
     <arr name="pivot"> 
     <lst> 
      <str name="field">text</str> 
      <str name="value">of</str> 
      <int name="count">135</int> 
     </lst> 
     <lst> 
      <str name="field">text</str> 
      <str name="value">the</str> 
      <int name="count">135</int> 
     </lst> 
     <lst> 
      <str name="field">text</str> 
      <str name="value">and</str> 
      <int name="count">123</int> 
[..] 

Schema.xml

<field name="year" type="int" indexed="true" stored="true" /> 
    <field name="text" type="text_en" indexed="true" stored="true" multiValued="true" /> 
    [..] 
    <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100"> 
      <analyzer type="index"> 
      <tokenizer class="solr.StandardTokenizerFactory"/> 
      <filter class="solr.LowerCaseFilterFactory"/> 
      <filter class="solr.EnglishPossessiveFilterFactory"/> 
      <filter class="solr.PorterStemFilterFactory"/> 
      </analyzer> 
      <analyzer type="query"> 
      <tokenizer class="solr.StandardTokenizerFactory"/> 
      <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/> 
      <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" /> 
      <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/> 
      <filter class="solr.LowerCaseFilterFactory"/> 
      <filter class="solr.EnglishPossessiveFilterFactory"/> 
      <filter class="solr.PorterStemFilterFactory"/> 
      </analyzer> 
     </fieldType> 
+0

Не могли бы вы немного разъяснить, почему ваши стоп-слова часто меняются? Мне интересно, нужен ли здесь другой подход. –

ответ

1

Не по вашему запросу?

http://ip:port/solr/collection1/select?q=*:*&rows=0&facet=true&facet.pivot=year,text 

Из того, что я вижу, вы ищете все, поэтому это означает, что он также вернет стоп-слова. Я имею в виду, если запрос получения передается в анализатор, класс фильтра анализатора видеть только

*:* 

, как запрос, так что я не думаю, что это будет удалить все из строки запроса таким образом.

Если вы действительно хотите найти все, но без каких-либо остановок, вы можете попробовать либо выполнить поиск с помощью negative query. Конечно, если вы используете это, вам нужно будет иметь другую конфигурацию, которая не фильтрует любые временные слова для запроса, тогда вы можете поместить стоп-слова вручную как отрицательный запрос, чтобы отфильтровать их. Таким образом, вы в основном ищете что-либо, но не учитываете результат, содержащий отрицательный запрос.

Но один простой способ (и лучший способ, по моему мнению), чтобы получить то, что вы хотите, - это фактически использовать поле копирования в конфигурации поля. Но это увеличит ваш размер индекса. Итак, что мы делаем здесь с нашим solr, помимо обычного поля, у нас есть другие языковые поля, такие как text_en, text_de, text_es и т. Д. И у нас есть детектор языка, который может обнаружить язык, скопировать поле на соответствующий язык и запустите правильный фильтр стоп-слов.

Вы также можете сделать это, если хотите, в своем schema.xml просто создать новое поле, text_en_filtered и скопировать текст из text_ru там и отфильтровать там временные слова. Затем вы можете просто искать в этом поле, которое больше не имеет никаких остановок.

<field name="text_en_filtered" type="text_en_filtered" indexed="true" stored="false" multiValued="false"/> 
<copyField source="text" dest="text_en_filtered"/> 
<fieldType name="text_en_filtered" class="solr.TextField" positionIncrementGap="100"> 
    ... // Analyzer with stopwords filtering here.. 
</fieldType> 
0

Извините, ваш вопрос непонятен. Так что я угадываю и пытаюсь ответить, что может быть вашим вопросом. Вот как обрабатываются стоп-слова. Если у вас есть <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" /> во время индексации, Solr не будет индексировать слова остановки, и вы не увидите эти слова в ваших фасетках. Кроме того, вам нужно использовать это во время запроса для правильных совпадений.

Если во время запроса у вас есть <filter class="solr.StopFilterFactory" ignoreCase="true" words="lang/stopwords_en.txt" />, вы удаляете только временные слова из фразы запроса до того, как Solr выполнит ваш запрос.

Обновление Неправильное понимание цепи анализа, по-видимому, является причиной вашего замешательства. Ваш параметр q - «:». Итак, если у вас есть StopFilterFactory во время запроса, как указано выше, вы будете фильтровать слова с «:», а не из результатов запроса. Вы будете получать все еще остаточные слова в своих результатах, поскольку вы фасетете по тексту. Вам нужно понять, что анализ времени запроса основан на QUERY, а не на результатах. В вашем «тексте» все еще есть временные слова, которые будут отображаться в результатах. В этом случае лучше и легко удалить результаты, которые не нужны на стороне клиента.

+0

Я только что редактировал мой вопрос. Надеюсь, теперь все ясно. Я также попытался понять ваш ответ, но я не совсем понятен. – Vilius

+0

Хорошо, переместите фильтр Stoppard от запроса к индексу и индексу re. – Arun

+0

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

1

Пожалуйста, просмотрите тему - does solr support query time only stopwords? из списка рассылки Solr.

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

+0

", в то время как запрос на стоп-слова возвращается 0 соответствует" IMHO решение в этом случае не применяется, так как StopFilter применяется к самому запросу, поэтому поэтому 0 совпадает (что не относится к огранке ..) –

0

Я боюсь, что вам придется переиндексировать, если только вы не сможете выкопать код огранки и отфильтровать их перед процессом агрегации. Вы можете ускорить процесс, уменьшив набор документов для переопределения только для документов, содержащих новое слово остановки в случае.