我需要在我的网站上进行部分搜索。最初我直接使用edgeNgramFeild它没有按预期工作。所以我使用自定义分析器的自定义搜索引擎。我正在使用Django-haystack。
'settings': {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "lowercase",
"filter": ["haystack_ngram"]
},
"edgengram_analyzer": {
"type": "custom",
"tokenizer": "lowercase",
"filter": ["haystack_edgengram"]
},
"suggest_analyzer": {
"type":"custom",
"tokenizer":"standard",
"filter":[
"standard",
"lowercase",
"asciifolding"
]
},
},
"tokenizer": {
"haystack_ngram_tokenizer": {
"type": "nGram",
"min_gram": 3,
"max_gram": 15,
},
"haystack_edgengram_tokenizer": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 15,
"side": "front"
}
},
"filter": {
"haystack_ngram": {
"type": "nGram",
"min_gram": 3,
"max_gram": 15
},
"haystack_edgengram": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 15
}
}
}
}
使用edgengram_analyzer
进行索引,使用suggest_analyzer
进行搜索。这在某种程度上起作用。但是,它并不适用于数字,例如,当输入30时,它不会搜索303,也会搜索包含字母和数字的单词。所以我搜索了各种网站。
他们建议使用标准或whitespace
标记器和haystack_edgengram
过滤器。但它并没有起作用,抛开数字部分搜索甚至不能用于字母表。建议后的设置:
'settings': {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "lowercase",
"filter": ["haystack_ngram"]
},
"edgengram_analyzer": {
"type": "custom",
"tokenizer": "whitepsace",
"filter": ["haystack_edgengram"]
},
"suggest_analyzer": {
"type":"custom",
"tokenizer":"standard",
"filter":[
"standard",
"lowercase",
"asciifolding"
]
},
},
"filter": {
"haystack_ngram": {
"type": "nGram",
"min_gram": 3,
"max_gram": 15
},
"haystack_edgengram": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 15
}
}
}
}
lowercase
tokenizer以外的任何其他内容都可以与django-haystack一起使用吗?或haystack_edgengram
过滤器不适合我。根据我的知识,它应该像这样工作。考虑2 Lazy Dog
提供的文本。它应该使用whitespace
[2,Lazy,Dog]
获得这样的令牌。然后应用haystack_edgengram
过滤器,它应该生成令牌[2,la,laz,lazy,do,dog]
。这样做不起作用。我做错了什么?
我的要求是例如文本2 Lazy Dog
,当某些类型2 Laz
应该有用时。
编辑:
在我的假设中,小写标记器正常工作。但是,如果是上述文本,则会省略2
并创建令牌[lazy,dog]
。为什么标准或空格标记器无法工作?
答案 0 :(得分:2)
在ngrams过滤器中,您可以定义min_gram,它是创建的令牌的最小长度。在你的情况下' 2'长度为1,因此在ngram过滤器中忽略它。
解决这个问题的最简单方法是将min_gram更改为1.更复杂的方法是将一些标准分析器与整个关键字相匹配(对于较短的术语很有用)和ngram analzyer用于部分匹配(对于较长的术语) - 也许有一些bool查询。
您还可以将ngrams更改为从' 1'在向Elasticsearch发送查询之前,搜索框中的字符至少需要3个字母。
答案 1 :(得分:-1)
我自己和@ jgr的建议找到了答案:
ELASTICSEARCH_INDEX_SETTINGS = {
"settings": {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["haystack_ngram"]
},
"edgengram_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["haystack_edgengram","lowercase"]
},
"suggest_analyzer": {
"type":"custom",
"tokenizer":"standard",
"filter":[
"lowercase"
]
}
},
"filter": {
"haystack_ngram": {
"type": "nGram",
"min_gram": 1,
"max_gram": 15
},
"haystack_edgengram": {
"type": "edgeNGram",
"min_gram": 1,
"max_gram": 15
}
}
}
}
}
ELASTICSEARCH_DEFAULT_ANALYZER = "suggest_analyzer"