2009-08-20 4 views
9

У нас есть база данных фильмов и сериалов, и поскольку данные поступают из многих источников различной надежности, мы хотели бы иметь возможность выполнять нечеткое сопоставление строк по названиям эпизодов. Мы используем Solr для поиска в нашем приложении, но механизмы согласования по умолчанию работают на уровнях слов, что недостаточно для коротких строк, например заголовковКак использовать сопоставление n-граммов с Solr?

Я использовал приблизительное сопоставление n-граммов в прошлом, и я был очень рад, что Lucene (и Solr) поддерживает что-то это из коробки. К сожалению, я не смог настроить его правильно.

Я предположил, что мне нужен специальный тип поля для этого, поэтому я добавил следующее поле типа моей schema.xml:

<fieldType 
    name="trigrams" 
    stored="true" 
    class="solr.StrField"> 
<analyzer type="index"> 
    <tokenizer 
     class="solr.analysis.NGramTokenizerFactory" 
     minGramSize="3" 
     maxGramSize="5" 
     /> 
    <filter class="solr.LowerCaseFilterFactory"/> 
</analyzer> 
</fieldType> 

и изменил соответствующее поле в схеме, чтобы:

<field name="title" type="trigrams" 
    indexed="true" stored="true" multiValued="false" /> 

Однако это не работает, как я ожидал. Анализ запроса выглядит правильно , но я не получаю никаких результатов, из-за чего я считаю, чточто-то происходит во время индекса (т. Е. Заголовок индексируется как поле строки по умолчанию вместо поля триграмм).

Запрос Я пытаюсь что-то вроде

title:"guy walks into a psychiatrist office" 

(с опечаткой или два), и она должна соответствовать «Guy Walks в Психиатр офис».

(я не совсем уверен, если запрос является правильным.)

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

Заранее благодарим за ответы.

+0

Вы можете разместить запрос, который вы используете? – olle

+0

Я редактировал вопрос, чтобы включить пример запроса. –

ответ

3

Решение оказалось очень простым: И был установлен как оператор по умолчанию, и если какая-либо из ngrams не соответствует, весь запрос завершился неудачно. Таким образом, было достаточно добавить:

<solrQueryParser defaultOperator="OR" /> 

в моей схеме.

+5

Ваш ответ показывает, что апостериорный вопрос не имеет ничего общего с ngrams. Я прав? –

+2

@ RyszardSzopa 'OR' вызывающе не совпадает с анализом n-грамм. 'OR' дает много результатов, но в целом неплохие результаты. –

9

Чтобы ответить на последнюю часть вашего вопроса: solr также имеет фильтр ngram. Таким образом, вы не должны использовать Ngram Tokenizer (но один, как «WhitespaceTokenizer», например), применяются все предварительно Ngram фильтры, а затем добавить этот один:

<filter class="solr.NGramFilterFactory" minGramSize="2" maxGramSize="3" />