在 Mapping 里面,将 dynamic 参数设置成 strict 可以拒绝索引包含未知字段的文档。 此条 Tips 由 medcl 贡献。

模糊匹配,且精确匹配时分数最高

Elasticsearch | 作者 jianghaibo | 发布于2018年09月23日 | 阅读数:3524

es2.x版本
 
使用n- gram
使用的索引
PUT /animal
{
"settings": {
"analysis": {
"filter": {
"trigrams_filter": {
"type": "ngram",
"min_gram": 1,
"max_gram": 50
}
},
"analyzer": {
"trigrams": {
"type": "custom",
"tokenizer": "standard",
"filter": [
"lowercase",
"trigrams_filter"
]
}
}
}
},
"mappings": {
"doc": {
"properties": {
"name": {
"type": "string",
"analyzer": "trigrams"
}
}
}
}
}
 查询语句
GET /animal/_search
{
"explain": false,
"query": {
"match": {
"name": {
"query": "ad",
"operator": "and"

}
}
}
}
使用如 上查询语句不会 将完全匹配的ad 放到最前面。

2018-09-23_215639.png

将查询 修改为如下:
GET /animal/_search
{
"explain": true,

"query": {
"function_score": {
"query": {
"match": {
"name": {
"query": "ad",
"operator": "and"
}
}

},
"script_score": {
"lang":"groovy",
"script": "user = doc['name'].value;factor = user.startsWith('ad')?1.1 :1.0;return _score * factor;"
}

}
}
}
还是不行
请教各位大神应该怎么做啊。谢谢。
已邀请:

rochy - rochy_he

赞同来自:

你这种方式推荐你使用 1 阶切分;也就是 ngram 的 min = max = 1;
你这里设置 50 个人感觉很不妥,没什么用,还非常占空间,同时索引速度也慢

搜索的时候使用 matchPhraseQuery 

cnlinjie

赞同来自:

解决了么?同遇到这个问题。。

cnlinjie

赞同来自:

解决了,加个排序,先按照分数排序,再按照字段排序。
我给title 加了个子字段。
GET /product/_search?size=15&from=0
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "iphone 5",
"fields": [
"title"
],
"type": "cross_fields",
"operator": "AND"
}
}
]
}
},
"sort": [{ "_score": { "order": "desc" }}, { "title.keyword": { "order": "asc" }}]
}


cnlinjie

赞同来自:

有些朋友有加我微信,问我解决方案。
说实话,这个方案本身好像有点小问题,但因为项目扑街,后续就没继续深入了,所以忘记是什么问题了。
我把当时的mapping.json文件导了出来,放在了附件里面,有需要参考的朋友可以看看。
 
字段我记得是title 那边。
具体的是:
 "title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
},
"suggest": {
"type": "completion",
"analyzer": "autocomplete",
"search_analyzer": "standard",
"preserve_separators": true,
"preserve_position_increments": true,
"max_input_length": 50
}
},
"analyzer": "autocomplete",
"search_analyzer": "standard"
}

要回复问题请先登录注册