如何使用Haystack进行部分场匹配?

时间:2010-12-08 19:51:20

标签: django search search-engine django-haystack

我需要一个简单的搜索工具来支持我的django网站,所以我选择了Haystack和Solr。我已正确设置所有内容,并且在输入完全短语时可以找到正确的搜索结果,但在键入部分短语时无法获得任何结果。

例如:“John”返回“John Doe”,但“Joh”不返回任何内容。

型号:

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)

搜索索引:

class PersonIndex(SearchIndex):
    text = CharField(document=True, use_template=True)
    first_name = CharField(model_attr = 'first_name')
    last_name = CharField(model_attr = 'last_name')

site.register(Person, PersonIndex)

我猜测有一些我缺少的设置可以实现部分字段匹配。我在一些论坛上看到有人在谈论EdgeNGramFilterFactory(),我用谷歌搜索过它,但我不太确定它的实现。另外,我希望有一种干草堆特定的方式,以防我切换搜索后端。

5 个答案:

答案 0 :(得分:16)

您可以通过将索引的文本字段设为EdgeNgramField:

来实现该行为
class PersonIndex(SearchIndex):
    text = EdgeNgramField(document=True, use_template=True)
    first_name = CharField(model_attr = 'first_name')
    last_name = CharField(model_attr = 'last_name')

答案 1 :(得分:2)

除了本页中其他人提及的EdgeNgramField提示(当然还有NgramField,如果您使用的是亚洲语言),我认为值得一提的是,在Django_haystack中你可以运行通过以下命令对Solr进行原始查询:

from haystack.query import SearchQuerySet
from haystack.inputs import Raw
SearchQuerySet().filter(text=Raw(query))

其中text是您要搜索的字段,query可以是基于Lucene的查询解析器语法(版本3.64.6)的任何内容。

通过这种方式,您可以轻松地将查询设置为ABC*ABC~或其他符合语法的内容。

答案 2 :(得分:1)

我在搜索非英语单词时遇到了类似的问题,例如:

ABC
ABCD

如果我想搜索关键字ABC,我会期待以上两个结果。通过将关键字转换为小写并使用startswith

,我能够实现以下目标
keywords = 'ABC'
results.filter(code__startswith=keywords.lower())

答案 3 :(得分:1)

我遇到了同样的问题,获得我想要的结果的唯一方法是修改solr配置文件以包含ngram过滤,因为默认的tokenizer基于空格。所以请改用NGramTokenizer。我很想知道是否有大海捞针做同样的事情。

我现在不在我的机器上,但这应该可以解决问题。

<tokenizer class="solr.NGramTokenizerFactory" minGramSize="3" maxGramSize="15" />

答案 4 :(得分:0)

@riz我还没有发表评论或者我会知道这是一个旧的评论,但万一有其他人跑过这个:确保manage.py update_index

  

Blockquote @Liarez你是如何让这个工作的?我使用干草堆/弹性搜索,我无法让它工作。