7

我在用作后端haystack的项目中使用。solr我希望能够执行包含搜索,类似于 Django.filter(something__contains="...")

__startswith选项不适合我们的需要,因为顾名思义,它会查找以字符串开头的单词。

我尝试使用类似*keyword*但 Solr 不允许*用作第一个字符

谢谢。

4

4 回答 4

9

要获得“包含”功能,您可以使用:

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

作为指标分析器。

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

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

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

"nde*"

它会匹配“ndex”给你一个打击。

请谨慎使用此方法,以确保您的索引不会变得太大。如果增加 minGramSize 或减少 maxGramSize,它不会将索引扩展为 mutch,而是减少“包含”功能。例如,设置 minGramSize="3" 将要求您在包含查询中至少有 3 个字符。

于 2011-06-14T07:31:48.503 回答
2

您无需接触 solr 模式即可实现相同的行为。在您的索引中,将您的文本字段设置为 EdgeNgramField 而不是 CharField。在引擎盖下,这将生成与 lindstromhenrik 建议的相似的模式。

于 2013-04-18T12:28:43.893 回答
0

这里没有一个答案是真正的子字符串搜索*keyword*

他们找不到属于较大字符串一部分的关键字(不是前缀后缀)。

在索引中使用EdgeNGramFilterFactoryorEdgeNgramField只能进行“ startswith ”或“ endswith ”类型的过滤。

解决方案是使用这样的NgramField

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

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

于 2013-12-19T18:27:39.957 回答
0

我正在使用如下表达式: .filter(something__startswith='...') .filter_or(name=' '+s'...') 似乎 solr 不喜欢像 ' ...*' 这样的表达式,但是结合或将做

于 2013-01-25T11:23:38.967 回答