如同磁铁吸引四周的铁粉,热情也能吸引周围的人,改变周围的情况。

搜索词 查询准确度问题

Elasticsearch | 作者 wengxuejie | 发布于2018年11月24日 | 阅读数:3409

请教大家一个问题,我现在有一个关键词 ck 牛仔裤  ,用了cross_field类型做搜索,具体语句如下:
{
"query": {
"bool": {

"must": {
"multi_match": {
"fields": [
"name^3",
"category_name^2",
"brand_name^2",
"brand_alias_name",
"sex",
"attribute",
"long_desc",
"condition_desc",
"brand_name_cn",
"name.synonym",
"brand_name.synonym",
"name.ikmax",
"name.sy_ikmax",
"brand_name_cn.synonym",
"brand_alias_name.synonym",
"attribute.synonym",
"long_desc.synonym",
"condition_desc.synonym",
"category_name.synonym"


],
"operator": "AND",
"query": "ck 牛仔裤",
"tie_breaker": 0.3,
"type": "cross_fields"
}
}
}
}
}

搜索结果前面出现的结果是很匹配的,但是 后面出现的结果都是命中某一个字段后出现的结果,相对来说很不准,所以想请教一下,如何精确拿到自己想要的数据,es有好的建议吗
已邀请:

core_wzw - 某AILab搜索技术负责人

赞同来自: wengxuejie

不一定非得要求19个字段每个字段都出现“ck”“牛仔裤”,一般情况下如果认为“title”“content”“keyword”每个字段都要出现“ck”“牛仔裤”的话,就可以认为是“精确搜索”了。
 
但说实话,一般ES拿来做全文搜索都不会要求是精确的,比如搜索【耐克 阿迪达斯 上衣】,如果使用operator为AND,则无论使用哪种multi_search type都无法匹配出商品,所以往往用multi_match都是设置operator为OR(默认就为OR),并且设置minimum_should_match为60%,这样就可以搜索出属于耐克和阿迪达斯的上衣了,这种情况相当于一种泛搜索,扩大召回集嘛,至于什么样的文档应该出现在Top100,只需要多写一些打分特征让相关度更高的文档排在前面即可。相关度一般的文档被排在10000th的位置,或者没被召回,谁在乎呢。:)

rochy - rochy_he

赞同来自:

去掉 "operator": "AND", 
去掉 "tie_breaker": 0.3,
type 换为 phrase
看一下效果;
如果觉得可以,你可以使用 disMaxQuery 将
multiMatchQuery type = phrase 与 multiMatchQuery 两种结合起来;这样即能保证准确度也能保证一定的查全率

wengxuejie

赞同来自:

刚试了一下,还是不满足我的需求,我想要ck牌子的牛仔裤,但是还有别的商品出现

rochy - rochy_he

赞同来自:

想要ck牌子的牛仔裤,你试试下面的,看看效果
"operator": "AND", 
"query": "ck 牛仔裤", 
"tie_breaker": 0.3, 
"type": "best_fields"
 
 

wengxuejie

赞同来自:

因为ck是品牌,落在了brand_name上, 牛仔裤可能落在品牌或者商品名上,看起来应该用cross_fields更合理,但是如何准确拿到ck牌子的牛仔裤

core_wzw - 某AILab搜索技术负责人

赞同来自:

{
"query": {
"bool": {

"must": {
"multi_match": {
"fields": [
"name^3",
"category_name^2",
"brand_name^2",
"brand_alias_name",
"sex",
"attribute",
"long_desc",
"condition_desc",
"brand_name_cn",
"name.synonym",
"brand_name.synonym",
"name.ikmax",
"name.sy_ikmax",
"brand_name_cn.synonym",
"brand_alias_name.synonym",
"attribute.synonym",
"long_desc.synonym",
"condition_desc.synonym",
"category_name.synonym"
],
"operator": "AND",
"query": "ck 牛仔裤",
"type": "cross_fields"
}
}
}
}
}
1.先把tie_breaker去掉,既然写了cross_fields而不是best_fields,那就不要加tie_breaker,即使es不会报错,但这有什么意义呢。
 
2.再惯例问下,用cross_fields的前提,这么多字段在mapping建索引的分词器都一样吗?大部分人用cross_fields的目的都是要以各字段的mapping一致才行,如果是则在cross_fields的基础上咱们继续说。
 
3.“但是 后面出现的结果都是命中某一个字段后出现的结果,相对来说很不准”,既然这个打分特征用了multi_match,operator=and,那么不管type是cross_fields还是best_fields、most_fields,意思都是只要19个字段里,只要有一个字段同时包含“ck”“牛仔裤”,那么这篇文档就会被召回,也就会出现召回集靠后的文档出现了仅有某个字段包含“ck”“牛仔裤”都能被召回,产生楼主说的体验感差,哪怕文档得分很低。

core_wzw - 某AILab搜索技术负责人

赞同来自:

那很简单,既然楼主要求“精确拿到自己想要的数据”,那这么写
{
"query": {
"bool": {
"must": {
"multi_match": {
"fields": [
"name"
],
"operator": "AND",
"query": "ck 牛仔裤",
"boost": 3
},
"multi_match": {
"fields": [
"category_name"
],
"operator": "AND",
"query": "ck 牛仔裤",
"boost": 2
},
........."multi_match": {
"fields": [
"category_name.synonym"
],
"operator": "AND",
"query": "ck 牛仔裤"
},

}
}
}
}

wengxuejie

赞同来自:

问题解决,把词拆开后分别去搜索,然后再做交集
代码如下:
"must": [
{
"multi_match": {
"fields": [
"name^10",
"category_name^5",
"brand_name^5",
"brand_alias_name^5",
"sex",
"attribute",
"long_desc",
"condition_desc",
"brand_name_cn",
"name.synonym",
"brand_name.synonym^2",
"brand_name_cn.synonym",
"brand_alias_name.synonym",
"category_name.synonym"
],
"query": "ck",
"type": "cross_fields",
"operator": "OR",
"minimum_should_match":1
}
},
{
"multi_match": {
"fields": [
"name^10",
"category_name^5",
"brand_name^5",
"brand_alias_name^5",
"sex",
"attribute",
"long_desc",
"condition_desc",
"brand_name_cn",
"name.synonym",
"brand_name.synonym^2",
"brand_name_cn.synonym",
"brand_alias_name.synonym",
"category_name.synonym"
],
"query": "牛仔裤",
"type": "cross_fields",
"operator": "OR",
"minimum_should_match":1
}
}
]
这是一种很精确的查询方式,如果想扩大曝光,可以做截断的方式来处理

laoyang360 - 《一本书讲透Elasticsearch》作者,Elastic认证工程师 [死磕Elasitcsearch]知识星球地址:http://t.cn/RmwM3N9;微信公众号:铭毅天下; 博客:https://elastic.blog.csdn.net

赞同来自:

建议:
1、default_operator 参数设置为:true, 走短语匹配的方式;
2、auto_generate_phrase_queries 参数设置为 true,走短语匹配。
 
以上2个参数能满足短语匹配的要求,可以进一步试试。

要回复问题请先登录注册