Django-Haystack与Solr集成的搜索功能

8
我正在使用solr作为后端,在项目中使用haystack。我希望能够执行包含搜索,类似于Django的.filter(something__contains="...")__startswith选项不适合我们的需求,因为它只会查找以该字符串开头的单词。
我尝试使用类似于*keyword*的东西,但是Solr不允许使用*作为第一个字符。
谢谢。

“keyword” 是一个完整的单词还是你想要搜索部分单词? - Mauricio Scheffer
返回已翻译的文本: 解决方案粘贴在这里:https://dev59.com/dHrZa4cB1Zd3GeqP12by#33260538 - shredding
4个回答

10

要实现“包含”功能,您可以使用:

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

作为索引分析器。

这将为字段中的每个空格分隔单词创建n-gram。例如:

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

正如您所看到的,这将大大扩展您的索引,但如果现在输入以下查询:

"nde*"

使用这种方法时要小心,以确保索引不会变得太大。如果增加minGramSize或减少maxGramSize,则不会如此扩展索引,但会降低“包含”功能。例如,设置minGramSize="3"将要求您在contains查询中至少有3个字符。


2

你可以通过将文本字段更改为EdgeNgramField而不是CharField来实现相同的行为,而无需触碰solr模式。在幕后,这将生成与lindstromhenrik建议的类似模式。


0
我正在使用类似下面的表达式: .filter(something__startswith='...') .filter_or(name=''+s'...') 因为看起来solr不喜欢像 '...*' 这样的表达式,但与or联合使用就可以了。

0

这里没有一个答案可以进行真正的子字符串搜索*关键字*

它们无法找到作为更大字符串一部分的关键字,(不是前缀或后缀)。

在索引中使用EdgeNGramFilterFactoryEdgeNgramField只能进行"startswith"或"endswith"类型的过滤。

解决方案是使用NgramField,如下所示:

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

这非常优雅,因为您不需要手动向schema.xml添加任何内容


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接