Django-Haystack с Solr содержит поиск

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

Вариант __startswith нам не подходит, так как он, как следует из названия, ищет слова, начинающиеся со строки.

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

Спасибо.


person neolaser    schedule 14.06.2011    source источник
comment
"ключевое слово" - это целое слово или вы пытаетесь найти части слова?   -  person Mauricio Scheffer    schedule 14.06.2011
comment
решение вставлено сюда: stackoverflow.com/a/33260538/333566   -  person shredding    schedule 21.10.2015


Ответы (4)


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

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

как индексный анализатор.

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

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

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

"nde*"

он будет соответствовать «ndex», давая вам хит.

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

person lindstromhenrik    schedule 14.06.2011

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

person Facundo Olano    schedule 18.04.2013

Я использую такое выражение, как: ...*', но в сочетании с или подойдет

person HolgT    schedule 25.01.2013

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

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

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

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

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

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

person Nahn    schedule 19.12.2013