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

Solr поиск хэштага или упоминаний

Мы используем solr версии 3.5 для поиска в Tweets, я использую WordDelimiterFactory со следующей настройкой, чтобы иметь возможность искать @username или #hashtags:

<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0" splitOnNumerics="0" preserveOriginal="1" handleAsChar="@#"/>

Я увидел следующий патч, но, похоже, он не работает, как я и ожидал, я что-то упустил?

https://issues.apache.org/jira/browse/SOLR-2059

Но поиск @username также возвращает результаты только для имени пользователя или #hashtag - это просто результат возврата для hastag. Как я могу это достичь?

Целый тип поля:

<fieldType name="textnostem" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
  <analyzer type="index">
    <charFilter class="solr.HTMLStripCharFilterFactory"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"
            />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>

<fieldType name="textnostem" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
  <analyzer type="index">
    <charFilter class="solr.HTMLStripCharFilterFactory"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"
            />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"/>      
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

<fieldType name="textnostem" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
  <analyzer type="index">
    <charFilter class="solr.HTMLStripCharFilterFactory"/>
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"
            handleAsChar="@#"
            />
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory"
            ignoreCase="true"
            words="stopwords.txt"
            enablePositionIncrements="true"
            />
    <filter class="solr.WordDelimiterFilterFactory" 
            generateWordParts="1" 
            generateNumberParts="1" 
            catenateWords="1" 
            catenateNumbers="1" 
            catenateAll="0" 
            splitOnCaseChange="0" 
            splitOnNumerics="0"
            preserveOriginal="1"
            handleAsChar="@#"
            />      
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>
4b9b3361

Ответ 1

ОК, поэтому, прочитав патч SOLR-2059, который вы упомянули, похоже, что они заменили атрибут handleAsChar на WordDelimiterFactory на атрибут types. Вот спецификация этого атрибута на странице "Анализаторы, токенизаторы и токены". Страница "Соль":

types = "wdfftypes.txt" позволяет настраивать токенизацию для этого фильтра. Файл должен существовать в каталоге solr/conf, а записи имеют форму (без кавычек) "% = > ALPHA" или "\ u002C = > DIGIT". Допустимыми типами являются: НИЖНЯЯ, ВЕРХНЯЯ, АЛЬФА, ЦИФРОВАЯ, АЛЬФАНАЯ, SUBWORD_DELIM.

Итак, если мы возьмем эту документацию, плюс пример файла из SOLR-2059, я бы рекомендовал следующее:

<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="0" splitOnNumerics="0" preserveOriginal="1" types="twittertypes.txt"/>

Затем определите файл twittertypes.txt следующим образом и поместите его в ту же папку, что и файл schema.xml в вашем экземпляре Solr (возможно, в папке conf).

 # A customized type mapping for WordDelimiterFilterFactory
 # the allowable types are: LOWER, UPPER, ALPHA, DIGIT, ALPHANUM, SUBWORD_DELIM
 #    
 # the default for any character without a mapping is always computed from 
 # Unicode character properties

 # Map the $, %, '.', and ',' characters to DIGIT 
 # This might be useful for financial data.
 @ => ALPHA
 \u0023 => ALPHA

Обратите внимание, что вам нужно использовать символ Unicode (UTF-8) для символа хэша, поскольку он рассматривается как комментарий в текстовом файле.

В соответствии со всей документацией это должно исправить вашу проблему и обработать символы # и @как альфа-символы, которые будут обеспечивать поведение, которое вы ищете.

Ответ 2

Вы также можете создать собственный токенайзер, который будет анализировать имена пользователей и хэштеги как специальные токены. Затем вы можете добавить пользовательский фильтр, который нормализует регистр этих имен пользователей и хэштегов (учитывая, что они не чувствительны к регистру), оставляя остальные токены без изменений:

<fieldType name="text_twitter" class="solr.TextField" positionIncrementGap="100" multiValued="true">
  <analyzer type="index">
    <tokenizer class="org.opentapioca.analysis.twitter.TwitterTokenizerFactory" />
    <filter class="org.opentapioca.analysis.twitter.TwitterLowercaseFilterFactory" />
  </analyzer>
  <analyzer type="query">
     <tokenizer class="org.opentapioca.analysis.twitter.TwitterTokenizerFactory" />
     <filter class="org.opentapioca.analysis.twitter.TwitterLowercaseFilterFactory" />
  </analyzer>
</fieldType>