es 查询案例分析

news2024/12/23 6:50:54

场景描述:

有这样一种场景,比如我们想搜索

title:Brown fox

body:Brown fox

文章索引中有两条数据,兔子和狐狸两条数据

PUT /blogs/_bulk
{"index": {"_id": 1}}
{"title": "Quick brown rabbits", "body": "Brown rabbits are commonly seen."}
{"index": {"_id": 2}}
{"title": "Keeping pets healthy", "body": "My quick brown fox eats rabbits on a regular basis."}

结果肯定是想要数据二,狐狸优先展示

但是,然后搜索的时候,会对搜素词 Brown fox 进行分词,导致数据一优先级更高

可以看下结果:
优先展示的是兔子,有 0.8 的算分,而狐狸只有 0.7 的算分

GET /blogs/_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": "Brown fox"
        }},
        {"match": {
          "body": "Brown fox"
        }}
      ]
    }
  }
}

原因分析:

bool should的算法过程:

  • 查询should语句中的两个查询
  • 加和两个查询的评分
  • 乘以匹配语句的总数
  • 除以所有语句的总数

上述例子中,title和body属于竞争关系,不应该将分数简单叠加,而是应该找到单个最佳匹配的字段的评分。

解决方案

方式一 dis_max

可以采用 dis max query

实例如下:可以看到此时达到了我们想要的结果

GET /blogs/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {
          "match":{
        "title": "Brown fox"
        }
        }, 
        {
          "match": {
          "body": "Brown fox"
        }
        }
      ]
    }
  }
}

这里简单解释一下这两种命令产生的原因:

类似 MySQL 可以使用 explain 关键字分析指令

先分析 bool should

如下看兔子这条数据,总算分是两个字段的算分之和

GET /blogs/_search
{
  "explain": true, 
  "query": {
    "bool": {
      "should": [
        {"match": {
          "title": "Brown fox"
        }},
        {"match": {
          "body": "Brown fox"
        }}
      ]
    }
  }
}

再来看 dis_max

如下同样看兔子的这条数据,可以看到,此时这条数据的总算分是其中一个字段的最大值

GET /blogs/_search
{
  "explain": true, 
  "query": {
    "dis_max": {
      "queries": [
        {
          "match":{
        "title": "Brown fox"
        }
        }, 
        {
          "match": {
          "body": "Brown fox"
        }
        }
      ]
    }
  }
}

dis_max 还可以使用 tie_breaker 控制非最大值字段的算分

tier breaker是一个介于0-1之间的浮点数。0代表使用最佳匹配;1代表所有语句同等重要。

  1. 获得最佳匹配语句的评分_score 。
  2. 将其他匹配语句的评分与tie_breaker相乘
  3. 对以上评分求和并规范化

最终得分=最佳匹配字段+其他匹配字段*tie_breaker

此时可以看到

兔子这条数据的算分 0.714258 = 0.6931471 + 0.21110919 * 0.1

0.1 就是 tier breaker 的数值

方式二 multi_mahch :

还记得之前篇章里面学到的 multi_match 多字段查询么

看到下面结果中的算分是不是有点似曾相识,

没错,multi_mahch 默认的查询方式就是两字段取最大值的方式

算分方式和上面一致,可以自行使用 explain 进行尝试

GET /blogs/_search
{
  "query": {
    "multi_match": {
      "query": "Brown fox",
      "fields": ["title","body"]
    }
  }
}

同样的 multi_mahch 也可以使用 tie_breaker 控制最佳匹配之外字段的算分

GET /blogs/_search
{
  "query": {
    "multi_match": {
      "type": "best_fields", 
      "query": "Brown fox",
      "fields": ["title","body"],
      "tie_breaker": 0.1
    }
  }
}

multi_mahch 有三种方式

best_fields

这种方式就是默认的方式,就不再演示了

GET /blogs/_search
{
  "query": {
    "multi_match": {
      "type": "best_fields", 
      "query": "Brown fox",
      "fields": ["title","body"]
    }
  }
}

most_fields

这种方式就是上面 bool should 求和的方式

GET /blogs/_search
{
  "query": {
    "multi_match": {
      "type": "most_fields", 
      "query": "Brown fox",
      "fields": ["title","body"]
    }
  }
}

cross_fields

跨字段查询

搜索内容在多个字段中都显示,类似 bool+dis_max 组合

PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}




# 可以使用cross_fields,支持operator
#与copy_to相比,其中一个优势就是它可以在搜索时为单个字段提升权重。
GET /address/_search
{
  "query": {
    "multi_match": {
      "query": "湖南常德",
      "type": "cross_fields",
      "operator": "and", 
      "fields": ["province","city"]
    }
  }
}

这里跨字段还有另一种方式:

可以用copy...to 解决,但是需要额外的存储空间

DELETE /address
# copy_to参数允许将多个字段的值复制到组字段中,然后可以将其作为单个字段进行查询
PUT /address
{
  "mappings" : {
      "properties" : {
        "province" : {
          "type" : "keyword",
          "copy_to": "full_address"
        },
        "city" : {
          "type" : "text",
          "copy_to": "full_address"
        }
      }
    },
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "长沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "广东","city": "广州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵阳"}

GET /address/_search
{
  "query": {
    "match": {
      "full_address": {
        "query": "湖南常德",
        "operator": "and"
      }
    }
  }
}

本次先分享到这里,感谢各位观看!!!感兴趣的小伙伴可以关注收藏,持续更新中~~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1511240.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle Primavera P6 数据库升级

前言 为了模拟各种P6测试,我常常会安装各种不同版本的p6系统,无论是P6服务,亦或是P6客户端工具Professional,在今天操作p6使用时,无意识到安装在本地的P6 数据库(21.12)出现了与Professional软…

对于stm32中printf函数的移植方法

一、准备工作 使用printf之前需要先打开工程选项,把use microLIB选项打开。microlib是keil为嵌入式平台优化的一个精简库,本文使用到的printf将会用到这个microlib。 二、对printf进行重定向 将printf打印的东西输出到串口,由于printf默认输…

关于分布式分片,你该知道的事儿

关于分布式分片,你该知道的事儿 前言一、关于分片方式的那些事儿1.1 按照Hash划分1.2 按照区间范围划分1.3 按照数据量划分1.4 来些例子1.4.1 Redis的分片划分1.4.2 Mongo的分片划分 二、关于分区再平衡的那些事儿2.1 基于固定分片数量2.2 基于动态分片数量2.3 基于…

让生活更加精致的APP?

晚上好,今天博主来介绍几款帮助你条理生活的APP,让你的生活更加精致,充满仪式感。 一.格志日记 一款以“格子”的方式记录日记的APP,非常简单明了,用户可以依据自己的喜好,来自由定义或者删除格…

初阶数据结构之---堆的应用(堆排序和topk问题)

引言 上篇博客讲到了堆是什么,以及堆的基本创建和实现,这次我们再来对堆这个数据结构更进一步的深入,将讲到的内容包括:向下调整建堆,建堆的复杂度计算,堆排序和topk问题。话不多说,开启我们今…

Python面向对象——程序架构

需求 创建图形管理器 -记录多种图形(圆形、矩形.) --提供计算总面积的方法, 要求:增加新图形,不影响图形管理器 测试: 创建图形管理器,存储多个图形对象。 通过图形管理器,调用计算总面积方法 思路 ​​​​​​​ 代码 # ------…

C# SM2加解密 ——国密SM2算法

SM2 是国家密码管理局组织制定并提出的椭圆曲线密码算法标准。 本文使用第三方密码库 BouncyCastle 实现 SM2 加解密,使用 NuGet 安装即可,包名:Portable.BouncyCastle,目前最新版本为:1.9.0。 using Org.BouncyCastl…

SpringBoot中MD5使用

SpringBoot中MD5使用 新建md5类 public final class MD5 {public static String encrypt(String strSrc) {try {char[] hexChars {0, 1, 2, 3, 4, 5, 6, 7, 8,9, a, b, c, d, e, f};byte[] bytes strSrc.getBytes();MessageDigest md MessageDigest.getInstance("MD5…

设计模式前置了解uml图

在开发前,会进行系统的设计,而数据模型的设计大多通过 UML 类图实现。为了在 UML 类图中清晰地表达类之间的关系,需要对类之间的关系有一定的认识,并且了解相关的表达符号。 类之间的关系有以下几种: 组合 聚合 关联…

IPC:管道

一、管道的概念 1.原理 在进程3G~4G的内核空间中,创建一个特殊的文件(管道),管道的数据直接保存在内存中。 2.特性 1)管道可以看成是一个特殊的文件,一般的文件存储在外存中,而管道内容是存储…

“光谱视界革新:ChatGPT在成像光谱遥感中的智能革命“

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用,人工智能…

docker——启动各种服务

1.Mysql 2.Redis 3.nginx 4.ES 注意:ES7之后环境为 -e ELASTICSEARCH_HOSTS http://ip地址:9200

双场板功率型GaN HEMT中用于精确开关行为的电容建模

来源:Capacitance Modeling in Dual Field-Plate Power GaN HEMT for Accurate Switching Behavior (TED 16年) 摘要 本文提出了一种基于表面电势的紧凑模型,用于描述具有栅极和源极场板(FP)结构的AlGaN/GaN高电子迁移率晶体管(…

在OpenStack架构中,Controller节点的配置(基础)

虚拟机的安装 新建虚拟机,选择自定义 默认选择即可 操作系统的镜像稍后选择 客户及操作系统选择Linux,注意选择centos 7 64位 给虚拟机命名 处理器的配置建议1:2 内存大小选择建议为:4GB 网络连接选择为:NAT 默认即可…

Redis底层核心对象RedisObject源码分析

文章目录 1. redis底层数据结构2. 插入KV底层源码流程分析 1. redis底层数据结构 redis 6数据结构和底层数据结构的关系 String类型本质是SDS动态字符串,即redis层面的数据结构底层会有对应的数据结构实现,上面是redis 6之前的实现 redis 7数据结构和底…

如何保证消息的顺序性

先看看顺序会错乱的场景:RabbitMQ:一个 queue,多个 consumer,这不明显乱了: 解决方案:

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的番茄新鲜程度检测系统(深度学习+UI界面+训练数据集)

摘要:本研究详述了一种采用深度学习技术的番茄新鲜程度检测系统,该系统集成了最新的YOLOv8算法,并与YOLOv7、YOLOv6、YOLOv5等早期算法进行了性能评估对比。该系统能够在各种媒介——包括图像、视频文件、实时视频流及批量文件中——准确地识…

智能泵站智能运维系统

在现代化城市建设和工农业发展中,泵站作为关键的水利设施,其运行效率和稳定性至关重要。然而,传统的泵站运维方式往往依赖于人工巡检和定期维护,这种方式不仅效率低下,而且难以应对突发状况。随着物联网技术的飞速发展…

支小蜜校园防欺凌系统真的能有效遏制欺凌现象吗?

随着社会的快速发展,校园欺凌问题逐渐浮出水面,引起了广泛关注。为了应对这一问题,校园防欺凌系统应运而生,旨在通过一系列措施,有效遏制欺凌现象的发生。然而,这一系统是否真的能够如预期般发挥作用&#…

软考高项(信息系统项目管理师)备考一、介绍

天行健,君子以自强不息;地势坤,君子以厚德载物。 每个人都有惰性,但不断学习是好好生活的根本,共勉! 文章均为学习整理笔记,分享记录为主,如有错误请指正,共同学习进步。…