elasticsearch的使用(二)
DSL查询
Elasticsearch的查询可以分为两大类:
-
叶子查询(Leaf query clauses):一般是在特定的字段里查询特定值,属于简单查询,很少单独使用。
-
复合查询(Compound query clauses):以逻辑方式组合多个叶子查询或者更改叶子查询的行为方式
语法示例:
GET /{索引库名}/_search
{"query": {"查询类型": {// .. 查询条件}}
}
无条件查询的类型是:match_all:
GET /items/_search
{"query": {"match_all": {}}
}
获取到的结果


你会发现虽然是match_all,但是响应结果中并不会包含索引库中的所有文档,而是仅有10条。这是因为处于安全考虑,elasticsearch设置了默认的查询页数。
叶子查询
叶子查询的类型也可以做进一步细分,详情大家可以查看官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/query-dsl.html
这里列举一些常见的,例如:
-
全文检索查询(Full Text Queries):利用分词器对用户输入搜索条件先分词,得到词条,然后再利用倒排索引搜索词条。例如:
-
match: -
multi_match
-
-
精确查询(Term-level queries):不对用户输入搜索条件分词,根据字段内容精确值匹配。但只能查找keyword、数值、日期、boolean类型的字段。例如:
-
ids -
term -
range
-
-
地理坐标查询:用于搜索地理位置,搜索方式很多,例如:
-
geo_bounding_box:按矩形搜索 -
geo_distance:按点和半径搜索
-
全文检索查询
全文检索的种类也很多,详情可以参考官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/full-text-queries.html
match(匹配单个字段),语法如下:
GET /{索引库名}/_search
{"query": {"match": {"字段名": "搜索条件"}}
}
使用实例:
GET /items/_search
{"query": {"match": {"name": "手机"}}
}
查询结果

multi_match(匹配多个字段):语法如下
GET /{索引库名}/_search
{"query": {"multi_match": {"query": "搜索条件","fields": ["字段1", "字段2"]}}
}
实例,我们搜索带华为二字的品牌与名字的商品
GET /items/_search
{"query": {"multi_match": {"query": "华为","fields": ["brand","name"]}}
}

精确查询
推荐查找keyword、数值、日期、boolean类型的字段。
详情可以查看官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/term-level-queries.html
term查询(精确查询某个字段的相同值的文档),语法如下:
GET /{索引库名}/_search
{"query": {"term": {"字段名": {"value": "搜索条件"}}}
}
实例,查询一个品牌为诺基亚的商品
GET /items/_search
{"query": {"term": {"brand": {"value": "诺基亚"}}}
}

range查询(处于某个字段范围内的文档),语法如下:
GET /{索引库名}/_search
{"query": {"range": {"字段名": {"gte": {最小值},"lte": {最大值}}}}
}
实例,查询价格处于500-1000的商品(由于数据库的存储单位为分,所以我们查询时多加两个零):
GET /items/_search
{"query": {"range": {"price": {"gte": 50000,"lte": 100000}}}
}

range是范围查询,对于范围筛选的关键字有:
-
gte:大于等于 -
gt:大于 -
lte:小于等于 -
lt:小于
复合查询
算分函数查询
采用的相关性打分算法是BM25算法,公式如下:

基本语法:
function score 查询中包含四部分内容:
-
原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
-
过滤条件:filter部分,符合该条件的文档才会重新算分
-
算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
-
weight:函数结果是常量
-
field_value_factor:以文档中的某个字段值作为函数结果
-
random_score:以随机数作为函数结果
-
script_score:自定义算分函数算法
-
-
运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:
-
multiply:相乘
-
replace:用function score替换query score
-
其它,例如:sum、avg、max、min
-
function score的运行流程如下:
-
1)根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)
-
2)根据过滤条件,过滤文档
-
3)符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)
-
4)将原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。
因此,其中的关键点是:
-
过滤条件:决定哪些文档的算分被修改
-
算分函数:决定函数算分的算法
-
运算模式:决定最终算分结果
实例,给IPhone这个品牌的手机算分提高十倍,分析如下:
-
过滤条件:品牌必须为IPhone
-
算分函数:常量weight,值为10
-
算分模式:相乘multiply
GET /hotel/_search
{"query": {"function_score": {"query": { .... }, // 原始查询,可以是任意条件"functions": [ // 算分函数{"filter": { // 满足的条件,品牌必须是Iphone"term": {"brand": "Iphone"}},"weight": 10 // 算分权重为2}],"boost_mode": "multipy" // 加权模式,求乘积}}
}
bool查询
bool查询,即布尔查询。就是利用逻辑运算来组合一个或多个查询子句的组合。bool查询支持的逻辑运算有:
-
must:必须匹配每个子查询,类似“与”
-
should:选择性匹配子查询,类似“或”
-
must_not:必须不匹配,不参与算分,类似“非”
-
filter:必须匹配,不参与算分
bool查询基本语法:
GET /items/_search
{"query": {"bool": {"must": [{"match": {"name": "手机"}}],"should": [{"term": {"brand": { "value": "vivo" }}},{"term": {"brand": { "value": "小米" }}}],"must_not": [{"range": {"price": {"gte": 2500}}}],"filter": [{"range": {"price": {"lte": 1000}}}]}}
}

出于性能考虑,与搜索关键字无关的查询尽量采用must_not或filter逻辑运算,避免参与相关性算分
我们要搜索手机,但品牌必须是华为,价格必须是900~1599,那么可以这样写:
GET /items/_search
{"query": {"bool": {"must": [{"match": {"name": "手机"}}],"filter": [{"term": {"brand": { "value": "华为" }}},{"range": {"price": {"gte": 90000, "lt": 159900}}}]}}
}

排序
elasticsearch默认是根据相关度算分(_score)来排序,但是也支持自定义方式对搜索结果排序。不过分词字段无法排序,能参与排序字段类型有:keyword类型、数值类型、地理坐标类型、日期类型等。
详细说明可以参考官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/sort-search-results.html
语法如下:
GET /indexName/_search
{"query": {"match_all": {}},"sort": [{"排序字段": {"order": "排序方式asc和desc"}}]
}
实例,按照商品价格进行排序
GET /items/_search
{"query": {"match_all": {}},"sort": [{"price": {"order": "desc"}}]
}
可以看到商品价格呈现降序

分页
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
基础分页
elasticsearch中通过修改from、size参数来控制要返回的分页结果:
-
from:从第几个文档开始 -
size:总共查询几个文档
类似于mysql中的limit ?, ?
官方文档如下:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html
基本语法:
GET /items/_search
{"query": {"match_all": {}},"from": 0, // 分页开始的位置,默认为0"size": 10, // 每页文档数量,默认10"sort": [{"price": {"order": "desc"}}]
}
深度分页
针对深度分页,elasticsearch提供了两种解决方案:
-
search after:分页时需要排序,原理是从上一次的排序值开始,查询下一页数据。官方推荐使用的方式。 -
scroll:原理将排序后的文档id形成快照,保存下来,基于快照做分页。官方已经不推荐使用。
详情见文档:
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html
总结:
大多数情况下,我们采用普通分页就可以了。查看百度、京东等网站,会发现其分页都有限制。例如百度最多支持77页,每页不足20条。京东最多100页,每页最多60条。
因此,一般我们采用限制分页深度的方式即可,无需实现深度分页。
高亮
-
高亮词条都被加了
<em>标签 -
<em>标签都添加了红色样式
高亮标签肯定是由服务端提供数据的时候已经加上的。
基本语法如下:
GET /{索引库名}/_search
{"query": {"match": {"搜索字段": "搜索关键字"}},"highlight": {"fields": {"高亮字段名称": {"pre_tags": "<em>","post_tags": "</em>"}}}
}
注意:
-
搜索必须有查询条件,而且是全文检索类型的查询条件,例如
match -
参与高亮的字段必须是
text类型的字段 -
默认情况下参与高亮的字段要与搜索字段一致,除非添加:
required_field_match=false
实例,我们将华为二字高亮显示
GET /items/_search
{"query": {"match": {"name": "华为"}},"highlight": {"fields": {"name": {"pre_tags": "<em>","post_tags": "</em>"}}}
}

总结:
查询的DSL是一个大的JSON对象,包含下列属性:
-
query:查询条件 -
from和size:分页条件 -
sort:排序条件 -
highlight:高亮条件
数据聚合
Bucket聚合
其实就是以分类(category)字段对数据分组。category值一样的放在同一组,属于Bucket聚合中的Term聚合。
基本语法如下:
GET /items/_search
{"size": 0, "aggs": {"category_agg": {"terms": {"field": "category","size": 20}}}
}
语法说明:
-
size:设置size为0,就是每页查0条,则结果中就不包含文档,只包含聚合 -
aggs:定义聚合-
category_agg:聚合名称,自定义,但不能重复-
terms:聚合的类型,按分类聚合,所以用term-
field:参与聚合的字段名称 -
size:希望返回的聚合结果的最大数量
-
-
-
带条件聚合
我们需要从需求中分析出搜索查询的条件和聚合的目标:
-
搜索查询条件:
-
价格高于3000
-
必须是手机
-
-
聚合目标:统计的是品牌,肯定是对brand字段做term聚合
语法如下:
GET /items/_search
{"query": {"bool": {"filter": [{"term": {"category": "手机"}},{"range": {"price": {"gte": 300000}}}]}}, "size": 0, "aggs": {"brand_agg": {"terms": {"field": "brand","size": 20}}}
}
Metric聚合
语法如下:
GET /items/_search
{"query": {"bool": {"filter": [{"term": {"category": "手机"}},{"range": {"price": {"gte": 300000}}}]}}, "size": 0, "aggs": {"brand_agg": {"terms": {"field": "brand","size": 20},"aggs": {"stats_meric": {"stats": {"field": "price"}}}}}
}
可以看到我们在brand_agg聚合的内部,我们新加了一个aggs参数。这个聚合就是brand_agg的子聚合,会对brand_agg形成的每个桶中的文档分别统计。
-
stats_meric:聚合名称-
stats:聚合类型,stats是metric聚合的一种-
field:聚合字段,这里选择price,统计价格
-
-
由于stats是对brand_agg形成的每个品牌桶内文档分别做统计,因此每个品牌都会统计出自己的价格最小、最大、平均值。
总结
aggs代表聚合,与query同级,此时query的作用是?
-
限定聚合的的文档范围
聚合必须的三要素:
-
聚合名称
-
聚合类型
-
聚合字段
聚合可配置属性有:
-
size:指定聚合结果数量
-
order:指定聚合结果排序方式
-
field:指定聚合字段
相关文章:
elasticsearch的使用(二)
DSL查询 Elasticsearch的查询可以分为两大类: 叶子查询(Leaf query clauses):一般是在特定的字段里查询特定值,属于简单查询,很少单独使用。 复合查询(Compound query clauses)&am…...
YOLOv8由pt文件中读取模型信息
Pytorch的pt模型文件中保存了许多模型信息,如模型结构、模型参数、任务类型、批次、数据集等 在先前的YOLOv8实验中,博主发现YOLOv8在预测时并不需要指定任务类型,因为这些信息便保存在pt模型中,那么,今天我们便来看看…...
js遍历效率
1w条数据,遍历效率 1、for 15s let t(new Date()).getTime()let a[]for(var i 0; i < 100000; i){a.push({id:i,val:i})}let ts[]for(var i 0; i < a.length; i){if(a[i].val!2 && a[i].val!4 && a[i].val!8){ts.push(a[i])}}let c(new D…...
QModbus例程分析
由于有一个Modebus上位机的需要,分析一下QModbus Slave的源代码,方便后面的开发。 什么是Modbus Modbus是一种常用的串行通信协议,被广泛应用于工业自动化领域。它最初由Modicon(目前属于施耐德电气公司)于1979年开发…...
Vue万字学习笔记(入门1)
目录 简介 Vue是什么 渐进式框架 单文件组件 API 风格 选项式 API (Options API) 组合式 API (Composition API) 创建一个 Vue 应用 挂载应用 DOM 中的根组件模板 应用配置 多个应用实例 模板语法 文本插值 原始 HTML Attribute 绑定 简写…...
Cesium手动建模模型用Cesiumlab转3D Tiles模型位置不对,调整模型位置至指定经纬度
Cesium加载3Dtiles模型的平移和旋转_3dtiles先旋转再平移示例-CSDN博客 Cesium 平移cesiumlab生产的3Dtiles切片模型到目标经纬度-CSDN博客 【ArcGISCityEngine】自行制作Lod1城市大尺度白膜数据_cityengine 生成指定坐标集指定区域的白模-CSDN博客 以上次ArcGISCityEngine制…...
学习C语言第23天(程序环境和预处理)
1. 程序的翻译环境和执行环境 在ANSIC的任何一种实现中,存在两个不同的环境 第1种是翻译环境,在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境,它用于实际执行代码。 2. 详解编译链接 2.1 翻译环境 每个源文件单独经过编…...
Ubuntu22.04安装
使用Vmware安装好后 首先执行下面命令,不然每次打开终端会出现To run a command as administrator (user root)… touch ~/.sudo_as_admin_successful换源 参考 sudo cp /etc/apt/sources.list /etc/apt/sources.list.baksudo gedit /etc/apt/sources.list清空…...
从入门到自动化:一篇文章掌握Python的80%
Python作为一种高级编程语言,以其简洁明了的语法和强大的功能性,在全球编程社区内享有极高的声誉。本文将带领你从Python的基础语法入手,介绍其常用库的应用,以及如何将Python用于数据分析、网络爬虫和简单的自动化任务࿰…...
开源的主流机器学习框架
主流的开源机器学习框架包括: 1. TensorFlow:由Google开发和维护的深度学习框架,广泛用于生产环境和研究。支持多种平台,并具有丰富的工具和库支持。 2. PyTorch:由Facebook开发的深度学习框架,以其动态计…...
RabbitMQ:发送者的可靠性之配置发送者重试机制
文章目录 为什么需要重试机制?如何配置重试机制?测试重试机制使用重试机制的注意事项 在使用消息队列(MQ)系统时,网络故障是不可避免的问题,尤其是在与RabbitMQ等服务交互时。如果生产者在发送消息时遇到网…...
基于深度学习的大规模MIMO信道状态信息反馈
MIMO系统 MIMO系统利用多个天线在发送端和接收端之间建立多条独立的信道,从而使得同一时间可以传输多个数据流,从而使得同一之间可以传输多个数据流,提高数据传输速率。 优势 增加传输速率和容量,提高信号覆盖范围和抗干扰能力…...
在Docker中部署Rasa NLU服务
最近因为项目需要将rasa nlu配置到docker容器中供系统调用,本篇主要整理该服务的docker配置过程。 本篇的重点在于docker的使用,不在Rasa NLU。 系统环境:Ubuntu 18.04.6 1. Rasa介绍 Rasa是一个开源的机器学习框架,专为构建基于文…...
SQL语句创建数据库(增删查改)
SQL语句 一.数据库的基础1.1 什么是数据库1.2 基本使用1.2.1 连接服务器1.2.2 使用案例 1.2 SQL分类 二.库的操作2.1 创建数据库2.2 创建数据库示例2.3 字符集和校验规则2.3.1 查看系统默认字符集以及校验规则2.3.2查看数据库支持的字符集2.3.3查看数据库支持的字符集校验规则2…...
微信小程序-Vant组件库的使用
一. 在app.json里面删除style:v2 为了避免使用Vant组件库和微信小程序组件样式的相互影响 二.在app.json里面usingComponents注册Vant组件库的自定义组件 "usingComponents": {"van-icon": "./miniprogram_npm/vant-weapp/icon/index&qu…...
为什么企业需要进行能源体系认证?
通过能源体系认证,企业可以向公众和利益相关方展示其在节能减排方面的承诺和成就。这不仅提升了企业的社会责任形象,还增强了品牌的信誉度。在当今消费者更加关注环境问题的背景下,绿色企业形象有助于赢得市场和客户的认可与信任。 能源体系认…...
【日常记录-MySQL】EVENT
Author:赵志乾 Date:2024-08-07 Declaration:All Right Reserved!!! 1. 简介 在MySQL中,EVENT是一种数据库对象,其用于设定数据库任务自动执行。这些任务可以是任意有效的SQL语句&a…...
嵌入式学习day12(LinuxC高级)
由于C高级部分比较零碎,各部分之间没有联系,所以学起来比较累,多练习就好了 一丶Linux起源 寻科普|第二期:聊聊Linux的前世今生 UNIX和linux的区别: (1)linux是开发源代码的自由软件.而unix是…...
pytorch中的hook机制register_forward_hook
上篇文章主要介绍了hook钩子函数的大致使用流程,本篇文章主要介绍pytorch中的hook机制register_forward_hook,手动在forward之前注册hook,hook在forward执行以后被自动执行。 1、hook背景 Hook被成为钩子机制,pytorch中包含forwa…...
使用Gin框架返回JSON、XML和HTML数据
简介 Gin是一个高性能的Go语言Web框架,它不仅提供了简洁的API,还支持快速的路由和中间件处理。在Web开发中,返回JSON、XML和HTML数据是非常常见的需求。本文将介绍如何使用Gin框架来返回这三种类型的数据。 环境准备 在开始之前࿰…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...
