Elasticsearch 论坛实战-使用copy_to定制组合field解决cross-fields搜索弊端

Elasticsearch实战

上一讲,我们说了,用most_fields策略,去实现cross-fields搜索,有3大弊端,而且搜索结果也显示出了这3大弊端

第一个办法:用copy_to,将多个field组合成一个field,问题其实就出在有多个field,有多个field以后,就很尴尬,我们只要想办法将一个标识跨在多个field的情况,合并成一个field即可。比如说,一个人名,本来是first_name,last_name,现在合并成一个full_name,不就ok了吗。。。。。

准备数据

PUT /forum?include_type_name=true
{
  "mappings": {
    "post":{
      "properties":{
        "first_name":{
          "type":"text",
          "copy_to":"full_name"
        },
        "last_name":{
          "type":"text",
          "copy_to":"full_name"
        },
        "full_name":{
          "type":"text"
        }
      }
    }
  }
}

POST /forum/post/_bulk
{ "index": { "_id": "1"} }
{ "first_name" : "Peter", "last_name" : "Smith" }
{ "index": { "_id": "2"} }
{ "first_name" : "Smith", "last_name" : "Williams" }
{ "index": { "_id": "3"} }
{ "first_name" : "Jack", "last_name" : "Ma" }
{ "index": { "_id": "4"} }
{ "first_name" : "Robbin", "last_name" : "Li" }
{ "index": { "_id": "5"} }
{ "first_name" : "Tonny", "last_name" : "Peter Smith" }

查询

 GET /forum/post/_search
 {
   "query": {
     "match": {
       "full_name": "Peter Smith"
     }
   }
 }

#! Deprecation: [types removal] Specifying types in search requests is deprecated.
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.4691012,
    "hits" : [
      {
        "_index" : "forum",
        "_type" : "post",
        "_id" : "1",
        "_score" : 1.4691012,
        "_source" : {
          "first_name" : "Peter",
          "last_name" : "Smith"
        }
      },
      {
        "_index" : "forum",
        "_type" : "post",
        "_id" : "5",
        "_score" : 1.2312969,
        "_source" : {
          "first_name" : "Tonny",
          "last_name" : "Peter Smith"
        }
      },
      {
        "_index" : "forum",
        "_type" : "post",
        "_id" : "2",
        "_score" : 0.5598161,
        "_source" : {
          "first_name" : "Smith",
          "last_name" : "Williams"
        }
      }
    ]
  }
}

注意⚠️:很无奈,很多时候,我们很难复现。比如官网也会给一些例子,说用什么什么文本,怎么怎么搜索,是怎么怎么样的效果。es版本在不断迭代,这个打分的算法也在不断的迭代。所以我们其实很难说,对类似这几讲讲解的best_fields,most_fields,cross_fields,完全复现出来应有的场景和效果。

总结

问题1:只是找到尽可能多的field匹配的doc,而不是某个field完全匹配的doc --> 解决,最匹配的document被最先返回

问题2:most_fields,没办法用minimum_should_match去掉长尾数据,就是匹配的特别少的结果 --> 解决,可以使用minimum_should_match去掉长尾数据

问题3:TF/IDF算法,比如Peter Smith和Smith Williams,搜索Peter Smith的时候,由于first_name中很少有Smith的,所以query在所有document中的频率很低,得到的分数很高,可能Smith Williams反而会排在Peter Smith前面 --> 解决,Smith和Peter在一个field了,所以在所有document中出现的次数是均匀的,不会有极端的偏差

欢迎访问我的个人博客:小马博客

项目源码关注公众号《JAVA拾贝》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JAVA拾贝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值