Elasticsearch 7.x Nested 嵌套类型查询 | ES 干货
一、什么是 ES Nested 嵌套
Elasticsearch 有很多数据类型,大致如下:
- 基本数据类型:
- string 类型。ES 7.x 中,string 类型会升级为:text 和 keyword。keyword 可以排序;text 默认分词,不可以排序。
- 数据类型:integer、long 等
- 时间类型、布尔类型、二进制类型、区间类型等
- 复杂数据类型:
- 数组类型:Array
- 对象类型:Object
- Nested 类型
- 特定数据类型:地理位置、IP 等
注意:tring/nested/array 类型字段不能用作排序字段。因此 string 类型会升级为:text 和 keyword。keyword 可以排序,text 默认分词,不可以排序。
2.1 那什么是 Nested 类型?
Elasticsearch 7.x 文档中,这样写到:
The nested type is a specialised version of the object datatype that allows arrays of objects to be indexed in a way that they can be queried independently of each other.
Nested (嵌套)类型,是特殊的对象类型,特殊的地方是索引对象数组方式不同,允许数组中的对象各自地进行索引。目的是对象之间彼此独立被查询出来。
2.2 如何使用 Nested 类型?
在 ES 的 my_index 索引中存储 users 字段。比如说:
{
"group" : "fans",
"users" : [
{
"name" : "John",
"age" : "23"
},
{
"name" : "Alice",
"age" : "18"
}
]
}
其实存储看上去跟 Object 类型一样,只不过底层原理对数组 users 字段索引方式不同。设置 users 字段的索引方式 Nested 嵌套类型:
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
"mappings": {
"properties": {
"users": {
"type": "nested"
}
}
}
}
'
二、Nested Query 应用场景或案例
比如小老弟我有一波小粉丝,users 字段类型是 object。存储如下:
{
"group" : "bysocket_fans",
"users" : [
{
"name" : "John",
"age" : "23"
},
{
"name" : "Alice",
"age" : "18"
}
]
}
{
"group" : "路人甲_fans",
"users" : [
{
"name" : "Alice",
"age" : "22"
},
{
"name" : "Jeff",
"age" : "18"
}
]
}
比如 18 岁大姑娘 Alice 是小老弟我的粉丝,她也可能是周杰伦的粉丝。那这边就有一个需求,即应用场景:
如何找到 18 岁大姑娘 Alice {"name" : "Alice","age" : "18"} 关注的所有明星呢?
如果用老的查询语句是这样搜索的:
GET /my_index/_search?pretty
{
"query": {
"bool": {
"must": [
{
"match": {
"users.name": "Alice"
}
},
{
"match": {
"users.age": 18
}
}
]
}
}
}
结果发现结果是不对的,路人甲 这条记录也出现了。
因为匹配到了第一个 Alice + 第二个 Jeff 的 18。所以这种查询不满足这个场景
那么需要使用 Nested 类型并用 Nested 查询,即让数组中的对象各自地进行索引。目的是对象之间彼此独立被查询出来。
三、Nested Query 实战
3.1 设置 Nested 类型
根据 2.2 如何使用 Nested 类型,将 users 字段类型从 object 修改为 nested:
curl -X PUT "localhost:9200/my_index" -H 'Content-Type: application/json' -d'
{
"mappings": {
"properties": {
"users": {
"type": "nested"
}
}
}
}
'
3.2 Nested Query
修改后,对应的 Nested Query ,如下:
GET /my_index/_search?pretty
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "users",
"query": {
"bool": {
"must": [
{
"match": {
"users.name": "Alice"
}
},
{
"match": {
"users.age": 18
}
}
]
}
}
}
}
]
}
}
}
语法很简单就是:
- key 以 "nested" 开头
- path 就是嵌套对象数组的字段名
- 其他
- score_mode (可选的)匹配子对象的分数相关性分数。avg (默认,使用所有匹配子对象的平均相关性分数)
- ignore_unmapped (可选的)是否忽略 path 未映射,不返回任何文档而不是错误。默认为 false,如果 path 不对就报错
这样查询得结果就是对的。
四、Nested Query 性能
这边测试过,给大家一个测试报告和建议。
压测环境:3 个 server ,6 个 ES 节点
压测结论: 使用上小节查询语句,50 并发情况下,导致千兆网卡被打满了。TPS 4000 左右,如果提高并发,就会增加 RT。所以如果高性能大流量情况下,必须用 Nested 应该从网络流量方向进行优化。二者,尽量减少大数据对象的返回
建议:泥瓦匠建议,你听听看
- 性能:Common Query 远远大于 Nested Query 远远大于 Parent/Child Query
- 性能优化:首先考虑减少后面两种 Query
- 性能优化:Nested Query 业务可以优化下。比如上一小节完全可以多存一个 fanIds 数组。搜索两次,第一次查确定 18 岁大姑娘 Alice 的 fanId,第二次根据 fanId 搜索即可
- 性能优化:实在没办法,高性能大流量情况下,必须用 Nested 应该从网络流量方向进行优化。二者,尽量减少大数据对象的返回
(完)
参考资料:
- https://blog.csdn.net/laoyang360/article/details/82950393
- https://www.elastic.co/guide/en/elasticsearch/reference/7.2/search-aggregations-bucket-reverse-nested-aggregation.html
Elasticsearch 7.x Nested 嵌套类型查询 | ES 干货的更多相关文章
- 使用ElasticSearch完成百万级数据查询附近的人功能
上一篇文章介绍了ElasticSearch使用Repository和ElasticSearchTemplate完成构建复杂查询条件,简单介绍了ElasticSearch使用地理位置的功能. 这一篇我们 ...
- [ES]Python查询ES导出数据为Excel
版本 elasticsearch==5.5.0 python==3.7 说明 用python查询es上存储的状态数据,将查询到的数据用pandas处理成excel code # -*- coding: ...
- RestHighLevelClient查询es
本篇分享的是es官网推荐的es客户端组件RestHighLevelClient的使用,其封装了操作es的crud方法,底层原理就是模拟各种es需要的请求,如put,delete,get等方式:本篇主要 ...
- 解决 Elasticsearch 超过 10000 条无法查询的问题
解决 Elasticsearch 超过 10000 条无法查询的问题 问题描述 分页查询场景,当查询记录数超过 10000 条时,会报错. 使用 Kibana 的 Dev Tools 工具查询 从第 ...
- elasticsearch 嵌套对象之嵌套类型
nested类型是一种特殊的对象object数据类型(specialised version of the object datatype ),允许对象数组彼此独立地进行索引和查询. 1. 对象数组如 ...
- 第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询
第三百六十六节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)的bool组合查询 bool查询说明 filter:[],字段的过滤,不参与打分must:[] ...
- Elasticsearch DSL语句之连接查询
传统数据库支持的full join(全连接)查询方式. 这种方式在Elasticsearch中使用时非常昂贵的.因此,Elasticsearch提供两种操作可以支持水平扩展 更多内容请参考Elasti ...
- elasticsearch的5种分片查询优先级
elasticsearch可以使用preference参数来指定分片查询的优先级,使用时就是在请求url上加上preference参数,如:http://ip:host/index/_search?p ...
- Elasticsearch笔记五之java操作es
Java操作es集群步骤1:配置集群对象信息:2:创建客户端:3:查看集群信息 1:集群名称 默认集群名为elasticsearch,如果集群名称和指定的不一致则在使用节点资源时会报错. 2:嗅探功能 ...
随机推荐
- Windows XP 每次开机都自动检测硬盘 解决办法(可以用HDDRegenerate修复坏道)
Windows XP,每次开机都自动检测硬盘,之前正常关机,没有任何非法操作.Windows XP,每次开机都自动检测硬盘,之前正常关机,没有任何非法操作. 1.和硬盘的分区格式有关,FAT32格式在 ...
- Qt5---ftp上传功能(使用组合的办法实现功能,QNetworkAccessManager自动管理分片上传,用QLoggingCategory屏蔽SSL警告)
从Qt的版本进化中可以知道,在Qt4中的QFtp类到了Qt5中已经没有了,虽然可以通过在Qt5中自己编译出QFtp,但是Qt5中提供的QNetworkAccessManager在发送和请求网络方面 ...
- DI 容器实务建议
整理一些有关使用 DI 容器的一些建议事项,主要的参考数据源是 Jimmy Board 的文章:Container Usage Guidelines. 1.容器设定 避免对同一个组件(DLL)重复扫描 ...
- QT 强制杀死进程
bool KillProcess(QString ProcessName){ bool result = false; QString str1; HANDLE hSnapShot = Create ...
- 数据备份服务商Rubrik获4000万美元B轮融资
搜狐科技 文/丽丽卡 5月27日,数据备份服务商Rubrik获Greylock Partners领投的4000万美元B轮融资,Lightspeed Venture Partners及其现有投资者跟投, ...
- ABP开发框架前后端开发系列---(7)系统审计日志和登录日志的管理
我们了解ABP框架内部自动记录审计日志和登录日志的,但是这些信息只是在相关的内部接口里面进行记录,并没有一个管理界面供我们了解,但是其系统数据库记录了这些数据信息,我们可以为它们设计一个查看和导出这些 ...
- LCN自动补偿
LCN自动补偿 1当出现需要补偿的数据的时候,LCN将请求tm.compensate.notifyUrl配置的通知地址, 请求补偿的样例数据格式: {"groupId":" ...
- 系统学习 Java IO (七)----字节数组流 ByteArrayInputStream/ByteArrayOutputStream
目录:系统学习 Java IO---- 目录,概览 ByteArrayInputStream 如果数据存储在数组中,ByteArrayInputStream 可以很方便读取,它可以返回 InputSt ...
- 【java】MD5加密工具
MD5: /** * 对指定字段进行MD5加密 * 参数为空或发生异常都会返回 @PASE-_FAIL (-1) * @author ZX * @date 2018年09月10日16:03:07 * ...
- 【简易bat脚本】启动java程序
前置条件:path中添加了JAVAHOME配置了java环境变量 1.新建txt文本文件 2.粘贴以下内容 @echo off set path=%path%;.;java -classpath &q ...