好的想法是十分钱一打,真正无价的是能够实现这些想法的人。

请教大神,ik中全匹配(确切的说,应该叫全包含)的排序问题如何解决?

Elasticsearch | 作者 intothephone | 发布于2018年07月23日 | 阅读数:3827

  •  待测试的文档,共有5条:


1 ---> "这一条应该排在最前面,因为全匹配北京青年图书馆,而且北京青年图书馆出现了两次", 
2 --->"这一条应该排在第二,只出现了一次北京青年图书馆,但还出现了北京青年,以及图书馆", 
3 --->"这一条应该排在第三,只出现了一次北京青年图书馆,其它的都没有了", 
4 --->"这一条应该排在第四,只有北京青年,但不是全匹配,而且还有图书馆" 
5 --->"这一条应该排在第五,只有图书馆",
 
  • mapping:


"properties": {
"content": {
"type": "string",
"store":"no",
"index":"analyzed",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
 
  • query:


{
"query": {
"match" : {
"content" : {
"query" : "北京青年图书馆"
}
}
},
"size":10
}

搜索结果的排序是:2, 3, 1, 4, 5
也就是说应该排第一位的,排到了第三位上。
也尝试了如下方案,都不行:
1)query改成用match_phrase,结果一条都搜不出来了。。。
2)analyzer改成ik_smart,query还是用match,那结果一样,排序是2,3,1,4,5
3)analyzer改成ik_smart,query用match_phrase,那只能搜到前三条,而且排序是2,3,1

要求其实很简单,就是全匹配(完全包含搜索词)的必须在前面,其它的只要包含搜索词里的部分就行,次序不重要。是不是哪里配置有问题,或者写的query不对?

大神及各位网友请多多指教,先谢谢各位!
已邀请:

intothephone

赞同来自:

排序是2,3,1,4,5:
{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "failed": 0
    },
    "hits": {
        "total": 5,
        "max_score": 0.3475853,
        "hits": [
            {
                "_index": "puretest",
                "_type": "item",
                "_id": "2",
                "_score": 0.3475853,
                "_source": {
                    "content": "这一条排在第二,只出现了一次北京青年图书馆,但还出现了北京青年,以及图书馆"
                }
            },
            {
                "_index": "puretest",
                "_type": "item",
                "_id": "4",
                "_score": 0.2949359,
                "_source": {
                    "content": "这一条排在第三,只出现了一次北京青年图书馆,其它的都没有了"
                }
            },
            {
                "_index": "puretest",
                "_type": "item",
                "_id": "1",
                "_score": 0.17939657,
                "_source": {
                    "content": "这一条应该排在最前面,因为全匹配北京青年图书馆,而且北京青年图书馆出现了两次"
                }
            },
            {
                "_index": "puretest",
                "_type": "item",
                "_id": "5",
                "_score": 0.15222305,
                "_source": {
                    "content": "这一条排在第四,只有北京青年,但不是全匹配,而且还有图书馆"
                }
            },
            {
                "_index": "puretest",
                "_type": "item",
                "_id": "3",
                "_score": 0.014625046,
                "_source": {
                    "content": "这一条排在第五,只有图书馆"
                }
            }
        ]
    }
}

zhoujie

赞同来自:

自定义script_score来实现你的逻辑,
{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "title": "用户"
              }
            }
          ]
        }
      },
     
      "script_score": {
        "script": "这里是你的逻辑"
      }
    }
  }
}    
 
请参考 https://www.elastic.co/guide/e ... ripts

rochy - rochy_he

赞同来自:

1)query改成用match_phrase,结果一条都搜不出来了:这个主要是你的search_analyzer和analyzer不一致造成的;

3)analyzer改成ik_smart,query用match_phrase,那只能搜到前三条,而且排序是2,3,1
 
所以当你执行 3)的操作:就可以搜到了,2排在第一位是因为第2条和第1条的匹配程度都是2次完全匹配(match_phrase匹配的意思是从前到后匹配,不是要完全挨在一起的意思),加上第2条文本短,所以得分高。
 
推荐你使用 dismax_query 把  match_phrase和match_query 结合到一起。

要回复问题请先登录注册