SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

2023-11-15

SpringCloud系列(十五)[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的还是对数据的搜索及分析, 因此本篇博客将对 ElasticSearch 的数据搜索功能进行演示.

①DSL 对文档的查询

常见查询类型:

  • 查询所有: 查询所有数据, 如 match_all;
  • 全文检索查询(full text): 主要利用分词器对用户的输入内容进行分词, 然后去倒排索引库中进行匹配查询, 如 match_query / multi_match_query;
  • 精确查询: 根据精确词条查询数据, 一般是用来查询日期 / 数值等类型的字段, 如 ids / range / term;
  • 地理查询(geo): 通常根据经纬度进行查询, 如 geo_distance / geo_bounding_box;
  • 复合查询(compound): 可以将上面的几种查询类型进行组合, 合并查询条件, 如 bool / function_score.

下面所有的查询语法基本如出一辙:

GET /索引库名/_search
{
  "query": {
    "查询类型": {
      "查询条件": "条件值"
    }
  }
}

1.1 查询所有

GET /hotel/_search
{
  "query": {
    "match_all": {}
  }
}

因为是查询所有的数据, 所以没有查询条件, 查询类型为 match_all, 查询所有一般用不到, 使用场景也就仅限于测试的时候使用;

1.2 全文检索查询

在这里插入图片描述

全文检索查询的使用场景比较多, 我们生活中也经常使用, 如在淘宝上买鞋子买衣服等, 都是搜索某一个牌子的名称或者是物品的名称, 也就是说需要拿着词条去索引库中匹配, 因此参与搜索的字段也必须是可分词的 text 类型的字段; 通过这个例子可以得到全文检索查询的基本流程如下:

  • 对搜索的内容进行分词得到词条;
  • 根据词条去倒排索引库中匹配, 得到文档 id;
  • 根据文档 id 找到文档, 然后返回到页面中.

关于全文检索的查询主要包括 match / multi_match 两种, 一个是单字段查询, 一个是多字段查询, 多字段查询的意思就是任意一个字段符合条件就满足查询条件. 示例如下:

match:

GET /hotel/_search
{
  "query": {
    "match": {
      "all":"喜来登"
    }
  }
}

在这里插入图片描述

multi_match:

GET /hotel/_search
{
  "query": {
    "multi_match": {
      "query":"上海喜来登",
      "fields": ["name","business"]
    }
  }
}

在这里插入图片描述
这里需要注意: multi_match 是根据多个字段进行查询, 参与的字段越多, 查询的效率就会越低, 因此一般使用 match 查询即可.

1.3 精准查询

精准查询的使用场景也是挺多的, 如查询某个日期范围内的数据, 或者是精确查询某一个地区的数据;

  • term: 根据词条精确值进行查询, 如查询北京地区的喜来登酒店, 筛选出的数据就只有北京地区的喜来登;
  • range: 根据值得范围进行查询, 如查询 500 元以上的酒店数据.

term 查询:

GET /hotel/_search
{
  "query": {
    "term": {
      "city": {
        "value": "上海"
      }
    }
  }
}

在这里插入图片描述
这里需要注意: 词条必须是精确的, 不能是多个词语组成的短语, 如果是北京上海, 是搜索不到结果的, 如下所示:
在这里插入图片描述

range 查询:

GET /hotel/_search
{
  "query": {
    "range": {
      "price": {
        "gte": "2000",
        "lte":"5000"
      }
    }
  }
}

查询到的是 2000 元到 5000 元价格酒店;
在这里插入图片描述

1.4 地理坐标查询


出去游玩打车或者订酒店经常需要进行定位附近的快车及酒店, 地理坐标的查询就能实现这样的功能, 一种是根据地理坐标的经纬度进行查询, 如根据矩形范围进行查询:

GET /hotel/_search
{
  "query": {
    "geo_bounding_box": {
      "FIELD": {
        "top_left": { 
          "lat": 31.35786,
          "lon": 121.59324
        },
        "bottom_right": {
          "lat": 31.35493,
          "lon": 121.59838
        }
      }
    }
  }
}

这里首先要确定左上角的点的坐标及右下角的点的坐标, 比较复杂, 但是有一种简单的方式, 可以根据距离进行查询, 查询到指定中心点小于某个距离值的所有数据; 也就是说以我现在的位置为中心, 距离我某个距离的圆弧内都符合条件, 如下所示:

GET /hotel/_search
{
  "query": {
    "geo_distance": {
      "distance": "5km",
      "location": "39.94076,116.46099"
    }
  }
}

这里我查询的是以三里屯为中心点, 距离三里屯 5 km 所有的数据:
在这里插入图片描述

1.5 复合查询

  复合查询可以将其简单的查询组合起来, 实现更加复杂的搜索逻辑, 主要有以下两种:

  • function score: 算分函数查询, 通过控制文档相关性算分, 来控制文档的排名;
  • bool query: 布尔查询, 主要利用逻辑关系组合多个查询, 实现复杂的搜索逻辑.

1.5.1 相关性算分

  当我们使用 match 进行查询时, 文档结果会根据与搜索词条的关联度进行打分, 返回的结果也会按照分值的降序进行排序;   ElasticSearch 早起使用的打分算法是 TF-IDF 算法, 关于算法的公式如下:
在这里插入图片描述
但是 TF-IDF 算法有一个缺陷: 当词条的频率越来越高的时候, 文档的得分也会越来越高, 单个词条对文档的影响较大. 针对这样的问题, ElasticSearch 将打分算法改进为 BM25, BM25 会让单个词条的算分有一个上限, 曲线更加的平滑.公式如下:
在这里插入图片描述

1.5.2 语法

GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "all": "北京"
        }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "id": "1"
            }
          },
          "weight": 10
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

在这里插入图片描述


如图所示, 可以看得出分数值是降序的, 具体的语法说明如下:
在这里插入图片描述
具体流程如下:

  • 根据原始条件查询搜索文档, 并且计算相关性算分, 也就是 query score (原始算分);
  • 根据过滤条件过滤掉不符合条件的文档;
  • 基于算分函数运算得到函数得分 (function score);
  • 将原始算分 (query score) 和 函数算分 (function score) 基于运算模式做运算, 得到相关性算分的最终结果.

例如: 给北京的喜来登排名靠前, 如下:
原始查询, 得分为 2.6944847;
在这里插入图片描述
添加算分函数后, 得分为 4.6944847, 如下:
在这里插入图片描述

1.5.3 布尔查询

在这里插入图片描述

  布尔查询的使用场景还是挺多的, 如上图在淘宝上搜索 阿迪达斯, 我们可以进行选择筛选, 可以根据鞋码 / 性别等; 因为每一个字段都是不同的, 查询的条件或者方式也不一样, 因此肯定是多个不同的查询, 那么要组合这些查询就用到了布尔查询;
 总之, 布尔查询也是一个或者多个字句的组合, 每一个字句都是一个子查询, 组合方式有:

  • must: 必须匹配每个子查询, 类似 “与”;
  • should: 选择性匹配子查询, 类似 “或”;
  • must_not: 必须不匹配, 不参与算分, 类似 “非”;
  • filter: 必须匹配, 不参与算分.

例子:

GET /hotel/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"city": "北京"}}
      ],
      "should": [
        {"term": {"brand":"希尔顿"}},
        {"term": {"brand":"喜来登"}}
      ],
      "must_not": [
        {"range": {"price": {"lte": 1200} }}
      ],
      "filter": [
        {"range": {
          "score": {
            "gte": 47
          }
        }},
        {"geo_distance": {
          "distance": "50km",
          "location": {
            "lat": 39.91979,
            "lon": 116.41804
          }
        }}
      ]
    }
  }
}

代码解读:
在这里插入图片描述


这里需要注意的是: 搜索过程中, 参与打字的字段越多, 查询的性能就会越差劲, 因此多条件查询时, 需要注意以下两点:

  • 搜索框的关键字搜索是全文检索查询, 使用 must 查询参与算分;
  • 其他的过滤条件采用 filter 查询, 不参与算分.

② 搜索结果的处理

③ RestClient 查询文档

④ 案例

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分) 的相关文章

随机推荐

  • 虚函数

    说一说虚函数 1 虚函数 就是在类的成员函数的前面加virtual关键字 2 虚函数通过虚函数表 虚表 来实现 虚表中存的是虚函数指针 3 虚函数和普通函数一样的 都是存在代码段的 只是他的指针又存到了虚表中 4 类的对象中存的是虚表指针
  • AndroidStudio 快速生成代码模板

    1 打开设置 File New Projects Settings Preferences for New Projects 不管什么版本 总之打开Settings 2 创建模板 1 搜索 Templates 模板 可以看到其实创建 cal
  • Git-用 cherry-pick 挑好看的小樱桃

    前篇 在此之前 我想问一个问题 你是在接触 Git 多久之后 知道有这个命令的 我的答案是很久很久之后 这真是一个悲伤的故事 懒 是万恶之源 此话果然不假 cherry pick 能干啥 cherry 中文翻译是樱桃 pick 中文翻译是采
  • 关系代数中的除法运算

    关系代数中的除法运算 这个概念的描述的非常抽象 刚开始学习的同学完全不知所云 这里通过一个实例来说明除法运算的求解过程 设有关系R S 如图所示 求R S 的结果 求解步骤过程 第一步 找出关系R和关系S中相同的属性 即Y属性 在关系S中对
  • Python-Pyqt6主窗口调用子窗口并互相传递参数

    功能实现 在主窗口点击按钮 调出子窗口 并向子窗口传递参数 在子窗口输入数据后再向主窗口传递参数 并在主窗口显示输入的数据 代码实现 1 载入图形化界面 在MainWinGUI py和ChildWinGUI py两个文件中编写主窗口和子窗口
  • maven 1、什么是maven

    什么是Maven 目前无论使用IDEA还是Eclipse等其他IDE 使用里面ANT工具 ANT工具帮助我们进行编译 打包运行等工作 Apache基于ANT进行了升级 研发出了全新的自动化构建工具Maven Maven是Apache的一款开
  • 计算机视觉基础2

    特征 颜色特征 几何特征 边缘 像素明显变化的区域 限速值函数快速变化的区域 一阶导数的机制区域 边缘提取 先高斯去噪 再使用一阶导数获取极值 导数对噪声敏感 边缘提取尺度问题 不同标准差的滤波 能捕捉到不同尺度的边缘 基于特征点的特征描述
  • 查看Linux下端口占用情况的命令

    在使用Linux系统的过程中 有时候会遇到端口被占用而导致服务无法启动的情况 比如HTTP使用80端口 但当启动Apache时 却发现此端口正在使用 这种情况大多数是由于软件冲突 或者默认端口设置不正确导致的 此时需要查看究竟哪个进程占用了
  • Python安装

    windows安装Python python官网 python官网下载 打开下载链接选择需要下载的python版本 点击版本号或者Download按钮进入下载页面 滚动到页面最下面可看到各个平台的 Python 安装包 选择Operatin
  • Unity按钮事件的几种绑定方式

    许久没有写C 代码了 对于一些东西自己给整忘了 在此记录下 方便以后自己查阅 获取到按钮组件 我是将代码挂载在其父节点上 一 代码动态绑定 在代码中获取此按钮 并对他就进行绑定 一般都是使用的这类情况 private Button back
  • OC 冒泡排序 ——时间排序

    NSMutableArray array NSMutableArray arrayWithObjects 2013 10 18 2013 10 11 2013 10 16 2013 10 15 2013 10 14 2013 10 13 2
  • 基于Java的迷宫小游戏

    一 实验内容 1 迷宫游戏是非常经典的游戏 在该题中要求随机生成一个迷宫 并求解迷宫 2 要求查找并理解迷宫生成的算法 并尝试用两种不同的算法来生成随机的迷宫 要求迷宫游戏支持玩家走迷宫 和系统走迷宫路径两种模式 玩家走迷宫 通过键盘方向键
  • springboot@Transactional事务不生效的几种解决方案

    springboot事务不生效的几种解决方案 最近在业务中遇到了很奇怪的场景 在加上 Transactional注解后 插入2条数据 如果第二条出异常了 第一条不会回滚 排查了很久 上网也找资料看了很久 问题得以解决 总结了事务不生效的几点
  • 完整、详细的MySQL规范

    一份非常完整 详细的MySQL规范 https mp weixin qq com s eCOn8JOPqExM6XOdv16krg 一 数据库命令规范 所有数据库对象名称必须使用小写字母并用下划线分割 所有数据库对象名称禁止使用mysql保
  • 学习记录681@Gitlab升级实战

    前言 我的Linux目前是centos8 目前使用的gitlab是从https mirrors tuna tsinghua edu cn 下载下来的gitlab ce 12 10 1 ce 0 el8 x86 64 rpm 然后安装的 这里
  • 面试前的准备和注意事项(非常详细)

    面试准备和注意事项 不论是校招还是社招都避免不了各种 试 笔试 如何去准备这些东 就显得格外重要 不论是 笔试还是 试都是有章可循的 我这个 有章可循 说的意思只是说应对技术 试是可以提前准 备 我其实特别不喜欢那种临近考试就提前背啊记啊各
  • 【教你两招!】弄懂3DMAX如何渲染通道图像

    3DMAX怎么渲染通道图 在3dmax中有多种意义的通道 一般我们说的通道主要是应用在图像的后期处理中 可以减少重复渲染的工作量 提高图像的品质 在3dmax中如何渲染通道图像 这里 沐风老师为大家准备了两种通道图像渲染的方法 一起来看看吧
  • C++入门教程

    今天 我心血来潮 打算为一些C 新手写点东西 1 DEV C 的安装 想写程序 就要有个编译器 这里推荐DEV C 当然 code blocks VS也行 下面是教程 下载DevC 有多种方式 根据需求选择自己觉得更方便的下载方式 具体根据
  • c++ 调用 python doc操作文件自动粘贴功能调研

    python安装环境准备 NOTICE 不建议使用conda库内的python库 调用会报ucrtbase dll错误 慎用 python3 6 6 支持vs2010 msvc120 python代码 import win32com fro
  • SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

    在SpringCloud系列 十五 分布式搜索引擎篇 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解 并且已经将一些数据进行了存储 但是这并不是我们学习 Elast