当前位置: 首页 > news >正文

【Elasticsearch教程13】Mapping字段类型之nested

Elasticsearch Mapping字段类型之nested

  • 一、简介
  • 二、插入测试数据
    • 1 创建nested字段的mapping
    • 2 插入2个班级的数据
  • 三、nested 查询
    • 1 Query DSL
    • 2 Java API
  • 四、nested 聚合
    • 1 Query DSL
    • 2 Java API
  • 五、nested的应用

一、简介

在上一篇博客Mapping字段类型之object中,已经验证了用object类型存放对象数组是不可取的,因为object会把多个对象进行扁平化存储。

nested类型能够存放对象数组,每一个对象会单独存储,所以可以在nested类型上进行查询聚合排序等操作。

然而nested类型也是有一些限制的,ES有如下默认设置:

  • 一个文档最多有50个nested类型的字段
  • 一个文档所有nested类型的字段存储文档最大数量是10000条

二、插入测试数据

1 创建nested字段的mapping

创建一个文档,存储班级和学生信息

PUT /pigg_test_nested/_mapping/
{
    "properties":{
        "class":{
            "type":"keyword"
        },
        "student":{
            "type":"nested",
            "properties":{
                "name":{
                    "type":"keyword"
                },
                "sex":{
                    "type":"keyword"
                },
                "age": {
                    "type":"integer"
                }
            }
        }
    }
}

2 插入2个班级的数据

PUT pigg_test_nested/_doc/1
{
    "class":"高三(1)班",
    "student":[
        {
            "name":"亚瑟王",
            "sex":"男",
            "age":20
        },
        {
            "name":"程咬金",
            "sex":"男",
            "age":30
        },
        {
            "name":"安其拉",
            "sex":"女",
            "age":18
        }
    ]
}

PUT pigg_test_nested/_doc/2
{
    "class":"高三(2)班",
    "student":[
        {
            "name":"孙策",
            "sex":"男",
            "age":20
        },
        {
            "name":"小乔",
            "sex":"女",
            "age":16
        },
        {
            "name":"大乔",
            "sex":"女",
            "age":18
        }
    ]
}

三、nested 查询

查询符合age=16 and name='女'学生的班级,返回id=2的文档

1 Query DSL

GET /pigg_test_nested/_search
{
  "query": {
    "nested": {           # nested关键字指定是在nested字段上做查询                            
      "path": "student",  # path指定需查询的字段名称
      "query": {		  # query指定查询体
        "bool": {
          "must": [
            {"term": {"student.age":  16 } }, # 写全路径名称,不能只是age 
            {"term": {"student.sex": "女"} }
          ]
        }
      }
    }
  }
}

2 Java API

  • QueryBuilders.nestedQuery指定是nested查询,第一参数填nested字段名称
  • 在查询条件中termQuery方法的第一参数要写全路径名称student.agestudent.sex
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(QueryBuilders.termQuery("student.age", 16));
boolQueryBuilder.must(QueryBuilders.termQuery("student.sex", "女"));

NestedQueryBuilder queryBuilder = QueryBuilders.nestedQuery(
        "student",
        boolQueryBuilder,
        ScoreMode.None);

四、nested 聚合

统计每个班中,男生和女生的人数

1 Query DSL

GET pigg_test_nested/_search
{
  "aggs": {
    "group_by_class": {			# 先按找班级class分组
      "terms": {
        "field": "class",
        "size": 10
      },
      "aggs": {
        "count_by_sex": {		
          "nested": {           # nested指定是在nested字段上聚合
            "path": "student"   # path指定nested字段名称student
          },
          "aggs": {             
            "group_by_sex": {   # 按照性别sex分组
              "terms": {
                "field": "student.sex",  # 写全路径名称,不能只是sex
                "size": 10
              }
            }
          }
        }
      }
    }
  }
}

返回如下:

"buckets" : [
        {
          "key" : "高三(1)班",
          "doc_count" : 1,
          "count_by_sex" : {
            "doc_count" : 3,
            "group_by_sex" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : "男",
                  "doc_count" : 2
                },
                {
                  "key" : "女",
                  "doc_count" : 1
                }
              ]
            }
          }
        },
        {
          "key" : "高三(2)班",
          "doc_count" : 1,
          "count_by_sex" : {
            "doc_count" : 3,
            "group_by_sex" : {
              "doc_count_error_upper_bound" : 0,
              "sum_other_doc_count" : 0,
              "buckets" : [
                {
                  "key" : "女",
                  "doc_count" : 2
                },
                {
                  "key" : "男",
                  "doc_count" : 1
                }
              ]
            }
          }
        }
]

2 Java API

  • 在用Java API时,也要注意用AggregationBuilders.nested指定nested字段名称
  • sex上做聚合时,要写全路径student.sex
AggregationBuilder agg = AggregationBuilders.terms("group_by_class").field("class")
        .subAggregation(
                AggregationBuilders.nested("count_by_sex", "student")
                        .subAggregation(
                                AggregationBuilders.terms("group_by_sex").field("student.sex")
                        )
        );

五、nested的应用

我常用nested类型用作自关联的嵌套结构,就是一个表中,有个parentId指向同一个表中的另外一条数据的ID。这就形成了树形结构,当然只有parentId是不够灵活的,所以每条记录要保存从根节点到自己的所有路径节点的id信息。具体可以参考我之前的博客ES 存储树形结构 整合Spring Data Elasticsearch

PUT /pigg_tree/_mapping/_doc
{
    "properties":{
        "id":{
            "type":"keyword"
        },
        "level":{
            "type":"keyword"
        },
        "name":{
            "type":"keyword"
        },
        "parentId":{
            "type":"keyword"
        },
        "path":{
            "type":"nested",
            "properties":{
                "id":{
                    "type":"keyword"
                },
                "level":{
                    "type":"keyword"
                }
            }
        }
    }
}

相关文章:

  • Java基础之:线程可重入锁,公平锁,非公平锁
  • MockServer 服务框架设计
  • 【web-利用信息泄露】(10.2)收集公布的信息、使用推论
  • java计算机毕业设计文档资料管理系统源码+系统+数据库+lw文档+mybatis+运行部署
  • JS中数组reduce()方法使用
  • 国稻种芯百团计划行动 任万军:减穴稳苗方法提高稻米品质
  • 新房IM转加私五步骤!!!
  • FPGA结构分析——ODDR,网口储备点2
  • DFS之剪枝与优化AcWing 166. 数独
  • 公司保护知识产权做法有哪些
  • Map和mybatis
  • 信息化与工业化融合,MES管理系统助力制造业发展
  • 国稻种芯百团计划行动 邓兴旺:依靠中国农业现代化的实现
  • Promethues入门,看懂不会写
  • Windows 10硬盘数据怎么永久擦除?
  • 4. 路由到控制器 - Laravel从零开始教程
  • Android 架构优化~MVP 架构改造
  • Android 控件背景颜色处理
  • Elasticsearch 参考指南(升级前重新索引)
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • rabbitmq延迟消息示例
  • React 快速上手 - 07 前端路由 react-router
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Service Worker
  • SwizzleMethod 黑魔法
  • 编写符合Python风格的对象
  • 不上全站https的网站你们就等着被恶心死吧
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 跨域
  • 浅析微信支付:申请退款、退款回调接口、查询退款
  • 使用agvtool更改app version/build
  • 想写好前端,先练好内功
  • 用quicker-worker.js轻松跑一个大数据遍历
  • 怎么把视频里的音乐提取出来
  • "无招胜有招"nbsp;史上最全的互…
  • # Maven错误Error executing Maven
  • (2020)Java后端开发----(面试题和笔试题)
  • (4.10~4.16)
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (js)循环条件满足时终止循环
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)php投票系统 毕业设计 121500
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (译)2019年前端性能优化清单 — 下篇
  • .gitignore
  • .NET 实现 NTFS 文件系统的硬链接 mklink /J(Junction)
  • .net访问oracle数据库性能问题
  • @angular/cli项目构建--http(2)
  • [ Linux 长征路第五篇 ] make/Makefile Linux项目自动化创建工具
  • [17]JAVAEE-HTTP协议
  • [2024最新教程]地表最强AGI:Claude 3注册账号/登录账号/访问方法,小白教程包教包会
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured