Джанго-Хейстек с Solr содержит поиск - PullRequest
7 голосов
/ 14 июня 2011

Я использую haystack в проекте, используя solr в качестве бэкэнда. Я хочу иметь возможность выполнять поиск содержимого, похожего на Django .filter(something__contains="...")

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

Я пытался использовать что-то вроде *keyword*, но Solr не позволяет использовать * в качестве первого символа

Спасибо.

Ответы [ 4 ]

9 голосов
/ 14 июня 2011

Чтобы получить «содержит» все функции, вы можете использовать:

<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="100" side="back"/>
<filter class="solr.LowerCaseFilterFactory" />

в качестве анализатора индекса.

Это создаст нграммы для каждого слова, разделенного пробелами в вашем поле.Например:

"Index this!" => x, ex, dex, ndex, index, !, s!, is!, his!, this!

Как вы видите, это значительно расширит ваш индекс, но если вы сейчас введете запрос, например:

"nde*"

, он будет совпадать с "ndex", что даст вам хит.

Используйте этот подход осторожно, чтобы убедиться, что ваш индекс не становится слишком большим.Если вы увеличите minGramSize или уменьшите maxGramSize, это не приведет к расширению индекса как к целому, а уменьшит функциональность «содержит».Например, установка minGramSize = "3" потребует, чтобы в вашем запросе содержалось не менее 3 символов.

1 голос
/ 18 апреля 2013

Вы можете добиться того же поведения, не касаясь схемы Solr. В вашем индексе сделайте ваше текстовое поле EdgeNgramField вместо CharField. Под капотом это создаст схему, аналогичную предложенной Линдстромхенриком.

0 голосов
/ 19 декабря 2013

Ни один из ответов здесь не выполняет реальный поиск по подстроке *keyword*.

Они не находят ключевое слово, являющееся частью большой строки (не префикс или суффикс ).

Использование EdgeNGramFilterFactory или EdgeNgramField в индексах может сделать только " начинается с " или " заканчивается с "тип фильтрации.

Решение состоит в том, чтобы использовать NgramField следующим образом:

class MyIndex(indexes.SearchIndex, indexes.Indexable):
    ...
    field_to_index= indexes.NgramField(model_attr='field_name')
    ...

Это очень элегантно, потому что вам не нужно ничего добавлять вручнуюв schema.xml

0 голосов
/ 25 января 2013

Я использую выражение вроде: .filter (что-то__startswith = '...') .filter_or (name = '' + s '...'), поскольку кажется, что solr не любит выражение типа ' ... * ', но в сочетании с или будет делать

...