我在使用haystack
作为后端的项目中使用solr
。我希望能够执行包含搜索,类似于Django .filter(something__contains="...")
__startswith
选项不符合我们的需要,顾名思义,它会查找以字符串开头的单词。
我尝试使用类似*keyword*
的内容,但Solr不允许将*
用作第一个字符
感谢。
答案 0 :(得分:9)
要获得“包含”功能,您可以使用:
<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,它不会将索引扩展为mutch,但会减少“contains”功能。例如,设置minGramSize =“3”将要求您在包含查询中至少包含3个字符。
答案 1 :(得分:1)
您无需触摸solr架构即可实现相同的行为。在索引中,将文本字段设置为EdgeNgramField而不是CharField。在引擎盖下,这将生成与lindstromhenrik建议的类似的模式。
答案 2 :(得分:0)
我使用的表达方式如下: .filter(something__startswith = '...') .filter_or(名称= '' + S'...') 因为似乎solr不喜欢' ... *'这样的表达,但与<或p>结合使用
答案 3 :(得分:0)
这里的答案都不是真正的子字符串搜索*keyword*
。
他们找不到属于较大字符串的关键字(不是前缀或后缀)。
在索引中使用EdgeNGramFilterFactory
或EdgeNgramField
只能执行“ startswith ”或“ endswith ”类型的过滤。< / p>
解决方案是使用 NgramField ,如下所示:
class MyIndex(indexes.SearchIndex, indexes.Indexable):
...
field_to_index= indexes.NgramField(model_attr='field_name')
...
这非常优雅,因为您无需手动向schema.xml添加任何内容