我用 elasticsearch 和 ik 插件做中文分词,但是搜索结果和预期不符。假设我有一段文本如下:
Markdown 与代码高亮测试
我如果使用关键词 Markdown
、代码
、代码高亮
等进行搜索,可以准确命中文档,但如果使用 代码测试
、Markdown 测试
等进行搜索,却检索不到文档,但如果把搜索关键词用空格进行分隔,有可以搜索到,例如 代码 测试
就可以命中文档。
所以从行为上来看,似乎是因为搜索时,elasticsearch 没有对搜索用的关键词进行分词,例如我搜 代码测试
,正确的行为应该是关键词被分词为 代码
、测试
,然后分别命中,从而返回搜索结果,但目前系统并没有,需要在关键词中插入空格,elasticsearch 才会进行如上分词。
查询 _mapping 接口返回的内容如下:
{
hellodjango_blog_tutorial: {
mappings: {
modelresult: {
properties: {
django_ct: {
type: "string",
index: "not_analyzed",
include_in_all: false
},
django_id: {
type: "string",
index: "not_analyzed",
include_in_all: false
},
id: {
type: "string"
},
text: {
type: "string",
analyzer: "ik_max_word"
}
}
}
}
}
}
可以看到索引分词正确使用了 ik_max_word 分词器。
analysis 配置如下:
'settings': {
"analysis": {
"analyzer": {
"ngram_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["haystack_ngram", "lowercase"]
},
"edgengram_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["haystack_edgengram", "lowercase"]
},
"ik_analyzer": {
"type": "custom",
"tokenizer": "ik_max_word",
}
},
"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
}
}
}
}
请问我应该如何调试,或者如何配置,才能有预期的行为。我使用的搜索框架是 django-haystack,elasticsearch 版本为 2.4.6