ElasticSearch DSL查询、排序 、分页的原理及语法

news2024/12/27 23:46:05
1. DSL查询分类和基本语法

ElasticSearch提供了基于Json的DSL来定义查询,常见的查询类型包括:
• 查询所有:查询出所有数据,一般测试用,一般不是查出所有,一次性查询20条。例如 match_all
• 全文检索(full text)查询:利用分词器对用户输入内容分词,然后去倒排索引中匹配,例如:
match_query、mutil_match_query
• 精确查询:根据精确词条查找数据,一般查找keyword、数值、日期、boolean等类型字段。例如:
ids、range(数字或者日期范围)、term(具体的某一个数字);
• 地理(geo)查询:根据经纬度查询。例如:
geo_diatance、geo_bounding_box
• 复合查询,复合查询可以将上述各种查询条件组合几来,合并查询条件,例如:
bool、function_score。

2. DSL全文检索查询语句

会对用户输入内容分词,常用于搜索框搜索。
match:根据一个字段查询,会对用户输入内容分词,然后去倒排索引库检索,语法:

GET/indexName/_search{
"query":{
     "match"{   #  查询方式,全文检索
        "FIELD":"TEXT"  # 字段:查询文本
            }
        }
}

multi_match:根据多个字段查询,参与查询字段越多,查询性能越差,语法:

Get/indexName/_search
{
"query":{
    "multi_match":{
        "query": "text",
        "fields": ["field1", "field2"]
            }
      }
}

如果想要查询多个字段,建议使用match,将多个字段使用copy to的方式拷贝到一个字段中去,创建一个新的字段名。

3. DSL精确查询语句

精确查询一般是查找keyword、数值、日期、boolean等类型字段,所以不会对搜索条件分词,常见的有:
term:根据词条精确值查询,语法如下:

Get/indexName/_search
{
    "query":{
        "term"{
           "FIELD"{
               "value": "value"
            }
        }
    }
}

range:根据值范围查询,例如根据日期,数值类型查询,语法如下:

Get/indexName/_search
{
  “query”:{
    "range":{
      "FIELD":{
          "gte": 10,
          "lte": 20
        }
      }
   }
}
4 .DSL地理查询语句

根据经纬度查询。常见得场景有:
• 携程:搜索我附近的酒店。
• 滴滴:搜索我附近的滴滴。
• 微信:收缩我附近的人。
地理查询的方式有很多总,如下:
• geo_bounding_box:查询geo_point 值落在某个矩形范围的所有文档,语法如下:

GET /indexName/search
{
      "query":{
          "geo_bounding_box":{
                  "FIELD":{
                      "top_left":{
                          "lat": 31.1,
                          "lon": 121.5
                  },
                      "bottom_right":{
                         "lat": 30.9,
                         "lon": 121.7
                 }
              }
          }
      }
}

top_left 和bottom_right代表地图上的两个点,以两个点为准,画出一个矩形,查询的是在矩形范围内的文档,如下图所示:
在这里插入图片描述
geo_distance:查询到指定中心点小于某个距离值的所有文档,语法如下:

GET /indexName/_search
{
   "query":{
        "geo_distance":{
                "distance:"15km",    ## 距离
                "FIELD": "31.21,121.5"   ## 中心点
               }
        }
}

如下图所示,查询的就是以31.21,121.5为中心点,小于15Km范围内的所有文档,适合用于查询附近的人的场景:
在这里插入图片描述

5. DSL复合查询

复合查询:可以将其他简单查询组合起来,实现更加复杂的搜索逻辑。

5.1 function score

算分函数查询,可以控制文档相关性算分,控制文档排名。例如,当我们利用match查询时,文件结果会根据与搜索词条的关联度打分,返回结果时按照分值降序排列。
如下图所示,我们搜索 “虹桥如家”,结果如下,会发现包含虹桥如家的分数最高,排在最前面。
在这里插入图片描述

打分的算法如下图所示:
在这里插入图片描述
ES中使用的是BM25算法,BM25算法相对于TF-IDF算法的优势就是,随着词频不断增加,相关性算分不会无限增加,而TF-IDF算法随着词频不断增加,相关性算分会不断无限增加,如下图所示:
在这里插入图片描述
总结:ES中的相关性打分算法在ES5.0之前采用的是TF-IDF,会随着词频增加而越来越大,在ES5.0之后,采用BM25,会随着词频增加而不断增大,但增长曲线会趋于水平。
上面介绍了ES的相关性打分,但是我们可以根据需求修改文档的相关性算分,人为控制排名,根据新得到的算分排序,就需要讲解function score query

5.2 复合查询- function score query

语法:

GET /hotel/_search
{
  "query":{
    "function score":{
      "query":{"match":{"all":"外滩"}}, ## 原始查询条件,搜索文档并根据相关性打分(query score)
      "functions":[
               {
                  "filter": {"term":{"id":"1"}},  ## 过滤条件,复合条件的文档才会被重新算分,例如这里是id为1的会重新算分
                  "weight": 10  
                  ## 算分函数,算分函数的结果称为function score,将来会与query score 运算,得到新的算分,常见的算分函数有
                  ## 1.weight:给一个常量值,作为函数结果(function score);
                  ## 2.field_value_factor:用文档中的某个字段值作为函数结果;
                  ## 3. random_score:随机生成一个值,作为函数结果;
                  ## 4. script_socre:自定义计算公式,公式结果作为函数结果
               }
             ],
           "boost mode":"multiply"
           ## 加权模式,定义function score与query score的运算方式,包括:
           ## 1.multiply:两者相乘。默认就是这个;
           ## 2.replace:用function score 替换 query score;
           ## 3.其他:sum、avg、max、min。
       }
    }
 }

案例:给“如家”这个品牌的酒店排名靠前一些。我们需要考虑function score的三要素:
• 哪些文档需要算分加权?这里就是对应的filter,品牌为如家的需要过滤。
• 算分函数是什么?这里我们可以选择weight算分函数。
• 加权模式是什么?这里对应的就是boost_mode,我们可以选择multiply。
查询语句如下:

GET /hotel/_search
{
 "query":{"
   function_score":{
     "query":{//..·},
     "functions":[ // 算分函数
       "filter":{ // 满足的条件,品牌必须是如家
         "term":{
           "brand":"如家"
           }
         },
       "weight":2 // 算分权重为2
       }
     },
    "boost_mode": "sum"
    }
  }
}
4.5.3 复合查询-Boolean Query

复合查询中的布尔查询是一个或多个查询子句的组合。子句的组合方式有:
• must:必须匹配每个子查询,类似“与”;
• should:选择性匹配子查询,类似“或”;
• must_not : 必须不匹配,不参与算分,类似 “非”;
• filter:必须匹配,不参与算分。
案例,如下图所示:
在这里插入图片描述

6. DSL搜索结果处理
6.1 排序

ES支持对搜索结果的排序,默认是根据相关度算分来排序。一旦指定自己的排序字段,ES就放弃相关度算分,查询的效率也会提升。可以排序的字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
keyword类型、数值类型、日期类型排序语法:

GET /indexName/_search
{
"query":{
    "match_all":{}
    },
"sort":[
   {
    "FIELD1": "desc"//排序字段和排序方式ASC、DESC
    },
    {
    "FIELD2": "asc"//排序字段和排序方式ASC、DESC
     }
    ]
  }

根据地理坐标排序语法:

GET /indexName/search
{
 "query":{
   "match_all":{}
  },
 "sort":[
  {
   "_geo_distance" :{
           "FIELD1":"纬度,经度",
            "order" : "asc",
            "unit" :"km"
          }
       }
    ]
}
6.2 分页

ES默认情况下只返回top 10条数据。而如果要查询更多数据就需要修改分页参数了。
ES中通过修改from 、size参数来控制要返回的分页结果,语法如下:

GET /hotel/_search
{
  "query": {
     "match_all": {}
   },
   "from":990,## 分页开始的位置,默认为0;
   "size":10,## 期望获取的文档总数
   "sort":[
         {"price": "asc"}
    ]
}

ES分页使用虽然跟mysql很像,只需要指定from,size即可,但原理和mysql存在较大的差异,ES分页的原理采用的是一种逻辑分页,假如现在
需要查990到1000的文档数据,如下图所示,ES会查出从0-1000的所有数据,然后截出990-1000的文档数据:
在这里插入图片描述
上面这种截取方式对于单个节点的ES是没有问题的,但是在实际情况下,为了能够存储更多的数据,那么ES是会进行集群部署的,一旦进行集群,ES就会对文档数据进行拆分,放到不同的机器上,如下图所示:
在这里插入图片描述
ES是分布式的,所以会面临深度分页的问题,例如现在按照price字段排序后,获取from = 990, size = 10的数据,那么就会获取0到1000的文档数据,然后截取,但是现在有多个ES集群部署了,如果只是截取某一台0-1000数据文档的10条数据那么就存在问题。ES集群情况下分页截取的原理如下:
• 首先在每个集群数据分片上都排序并查询前1000条文档;
• 然后将所有节点的结果聚合,在内存中重新排序选出前1000条文档;
• 最后从这1000条中,选取从990开始的10条文档。

如果搜索页数过深,或者结果集(from+size)越大,对内存和CPU的消耗也越高。因此ES设定结果集查询的上限是10000,一旦超过10000,就会报错,一般我们在实际情况中,从业务层面就限定查询不能超过10000条,如果实际的业务就要查询超过10000条,ES提供了两种解决办法:
• search after:分页时需要排序,原理是从上一次的排序字段后的末尾值开始,走位查询条件,查询下一页数据,分页只能往后翻,不能往前翻。官方推荐使用的方式;
• scroll:原理将排序数据形成快照,保存在内存,对内存消耗非常大。官方已经不推荐使用。

总结:
from + size:
• 优点:支持随机翻页;
• 缺点:深度分页问题,默认查询上限(from+size)是10000场景;
• 百度、京东、谷歌、淘宝这样的随机翻页搜索。
after search :
• 优点:没有查询上限(单次查询的size不超过10000);
• 缺点:只能向后逐页查询,不支持随机翻页;
• 场景:没有随机翻页需求的搜索,例如手机向下滚动翻页。
scroll:
• 优点:没有查询上限(单次查询的size不超过10000);
• 缺点:会有额外内存消耗,并且搜索结果是非实时的
• 场景:海量数据的获取和迁移。从ES7.1开始不推荐,建议用 aftersearch方案。

6.3 高亮

就是在搜索结果中把搜索关键字突出显示。
原理如下:
• 将搜索结果中的关键字用标签标记出来
• 在页面中给标签添加css样式
语法如下:

GET /hotel/_search
{
  "query":{
    "match" :{
      "FIELD": "TEXT"
    }
 },
"highlight": {
 "fields":{ ## 指定要高亮的字段
  "FIELD":{
    "pre_tags": "<em>", ## 用来标记高亮字段的前置标签
    "post_tags":"</em>” ## 用来标记高亮字段的后置标签
    }
   }
  }
 }

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

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

相关文章

『智能遥控新境界』:远程控制APP,高效生活的秘诀!

在这个科技日新月异的时代&#xff0c;我们的生活被各种手机软件所包围。几乎每个人都有一个甚至多个手机&#xff0c;你是否也有遇到过需要远程操作自己某一台手机的场景呢&#xff1f;今天&#xff0c;我要向大家推荐一款神奇的手机远程操作神器&#xff0c;让你可以随时随地…

基于 java springboot+layui仓库管理系统

基于 java springbootlayui仓库管理系统设计和实现 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取源…

力扣102 二叉树的层序遍历 Java版本

文章目录 题目描述思路代码 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[[3],[…

VsCode编译wxWidgets的HelloWorld

wxWidgets 环境搭建 在wxWidgets 官网下载页面点击Download Windows Binaries选择TDM-GCC 10.3和MinGW-w64 8.1下的头文件和开发包进行下载。这儿我们会用两种 gcc 编译器进行对比&#xff0c;所以下载 2 个种编译器对应的库文件。正常只需根据自己安装的编译器下载对应的 1 种…

Stable Diffusion 模型分享:Indigo Furry mix(人类与野兽的混合)

本文收录于《AI绘画从入门到精通》专栏,专栏总目录:点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八案例九案例十

再添数十种回归模型!最全机器学习预测全家桶,MATLAB代码,这次千万别再错过了!

截止到本期&#xff0c;一共发了14篇关于机器学习预测全家桶MATLAB代码的文章。算上这一篇&#xff0c;一共15篇&#xff01;参考文章如下&#xff1a; 1.五花八门的机器学习预测&#xff1f;一篇搞定不行吗&#xff1f;http://mp.weixin.qq.com/s?__bizMzkyNDUwMjc3Mg&m…

UIKit 在 UICollectionView 中拖放交换 Cell 视图的极简实现

概览 UIKit 中的 UICollectionView 视图是我们显示多列集合数据的不二选择&#xff0c;而丰富多彩的交互操作更是我们选择 UICollectionView 视图的另一个重要原因。 如上图所示&#xff1a;我们实现了在 UICollectionView 中拖放交换任意两个 Cell 子视图的功能&#xff0c;这…

JAVAEE初阶 网络编程(十二)

HTTP协议 一. 状态码1.200 OK2. 404 NOT FOUND3.403 forbidden4. 405 Method Not Allowed5. 500 Interval Server Error6.504 Gateway Timeout7.302 Move temporarily 二. 如何构造HTTP请求1.通过第三方工具构造. 二.HTTPS三. 密码学中的重要概念1.明文2.密文3.密钥4.对称加密5…

SpringBoot+MybatisPlus+Mysql实现批量插入万级数据多种方式与耗时对比

场景 若依前后端分离版本地搭建开发环境并运行项目的教程&#xff1a; 若依前后端分离版手把手教你本地搭建环境并运行项目_本地运行若依前后端分离-CSDN博客 若依前后端分离版如何集成的mybatis以及修改集成mybatisplus实现Mybatis增强&#xff1a; https://blog.csdn.net…

“TypeError: utils request jS WEBPACK IMPORTED MODULE O .default is undefined‘报错

写项目时报下列错误&#xff0c;找了半天&#xff0c;结果才发现自己在request.js中少写了一行代码 一定不要少些代码 export default requestrequest.js完整代码 import axios from axios;//创建一个新的axios对象 const request axios.create({baseURL:http://localhost:…

《springcloud alibaba》 一 Openfeign

准备 创建三个项目 父项目pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://mav…

[WebDav] WebDav基础知识

文章目录 什么是WebDavWebDav常用命令WebDav常用命令的测试&#xff08;代码&#xff09;PROPFIND 方法测试PUT 方法测试GET 方法测试PROPPATCH方法 WebDav缓存Cache-ControlEtag测试 强制重新验证不需要缓存 WebDav的锁WebDav的状态码WebDav身份验证WebDav版本控制WebDav和FTP…

mplfinance 使用make_addplot做复杂股票走势图

mplfinance 使用make_addplot做复杂股票走势图 1.代码 import talib as tb import pandas as pd import mplfinance as mpfimport matplotlib.pyplot as pltplt.rcParams[font.sans-serif][simHei] # 以黑体显示中文 plt.rcParams[axes.unicode_minus]False # 解决保存图像符…

通俗易懂分析:Vite和Webpack的区别

1、对项目构建的理解 先从浏览器出发&#xff0c; 浏览器是由浏览器内核和JS引擎组成&#xff1b;浏览器内核编译解析html代码和css代码&#xff0c;js引擎编译解析JavaScript代码&#xff1b;所以从本质上&#xff0c;浏览器只能识别运行JavaScript、CSS、HTML代码。 而我们在…

基于CNN-GRU-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 CNN&#xff08;卷积神经网络&#xff09;部分 4.2 GRU&#xff08;门控循环单元&#xff09;部分 4.3 Attention机制部分 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版…

STM32基于寄存器编程

在51中让一个引脚输出高低电平只需要一个步骤&#xff0c;而在32中至少需要三个步骤。 开启对应GPIO的时钟配置对应IO口设置IO口 本文将一步步进阶的讲解&#xff0c;三种寄存器编程的方法。 使用地址赋值进行配置使用ST的宏进行配置只控制需要的位&#xff08;位运算&#…

无/自监督去噪(2)——Noise2Noise (N2N) 理论分析(从损失函数入手)

目录 读前须知1. 前置知识——L1和L2 loss的特性2. additive Gaussian noise (spatial independent noise), L 2 L_2 L2​首杀3. brown Gaussian noise (spatial dependent noise), L 2 L_2 L2​双杀4. blind text removal, L 2 L_2 L2​导致结果偏灰, L 1 L_1 L1​前来破局…

刚开的抖店怎样推广?找主播带货,积累资源/渠道,拉动自然流量成交

我是王路飞。 2024年&#xff0c;依旧有很多人想入局抖音小店。 刚复工没几天&#xff0c;我就已经收到好多粉丝朋友的私信了&#xff0c;纷纷表示自己已经开通了抖店了&#xff0c;但是不会运营&#xff0c;现在新店应该怎样进行推广呢&#xff1f; 这篇内容就给你们详细说…

交换瓶子【第七届】【省赛】【A组】

题目描述 有N个瓶子&#xff0c;编号 1 ~ N&#xff0c;放在架子上。 比如有5个瓶子&#xff1a; 2 1 3 5 4 要求每次拿起2个瓶子&#xff0c;交换它们的位置。 经过若干次后&#xff0c;使得瓶子的序号为&#xff1a; 1 2 3 4 5 对于这么简单的情况&#xff0c;显然&#…

stm32——hal库学习笔记(DAC)

这里写目录标题 一、DAC简介&#xff08;了解&#xff09;1.1&#xff0c;什么是DAC&#xff1f;1.2&#xff0c;DAC的特性参数1.3&#xff0c;STM32各系列DAC的主要特性 二、DAC工作原理&#xff08;掌握&#xff09;2.1&#xff0c;DAC框图简介&#xff08;F1&#xff09;2.2…