如果你对ES不了解但是现在想知道他是干什么的,可以先查看我的其他几篇文档:

ElasticSearch究竟是个什么东西

通过官方文档高效学习ElasticSearch的JavaAPI实现!

如何在自己的项目中引入ElasticSearch搜索引擎?

ElasticSearch聚合查询Restful语法和JavaApi详解(基于ES7.6)

(一)ES如何存储对象

ElasticSearch中可以将数据以对象的方式存储并查询,但是ES底层的Lucene 没有内部对象的概念,因此如果通过默认的方式往ES中插入对象,ES会将对象层次结构扁平化为字段名称和值的简单列表。
比如下面这一段数据:

PUT my_index/_doc/1
{"group" : "fans","user" : [ {"first" : "John","last" :  "Smith"},{"first" : "Alice","last" :  "White"}]
}

ES内部会将这份数据变成下面这个样子:

{"group" :        "fans","user.first" : [ "alice", "john" ],"user.last" :  [ "smith", "white" ]
}

缺失了first和last之间的关联性。比如这个时候想查询一个first为John,last为White的人,理论上是没有这个人的,但是实际上名为fans的这个组还是被查出来了。

GET my_index/_search
{"query": {"bool": {"must": [{ "match": { "user.first": "John" }},{ "match": { "user.last":  "White" }}]}}
}

从结果可以看到,两条数据都被查询出来了。

(二)Nested类型

这个时候就需要用到nested,nested类型是object数据类型的特殊版本,它允许对象数组以一种可以相互独立查询的方式进行索引。

在Nested内部,每个对象索引其实是一个单独的隐藏文档,这意味着每个嵌套对象都可以独立于其他对象进行查询。

使用Nested需要先创建索引,依旧通过上边的这个例子

DELETE my_indexPUT my_index
{"mappings": {"properties": {"user": {"type": "nested" }}}
}PUT my_index/_doc/1
{"group" : "fans","user" : [{"first" : "John","last" :  "Smith","age" : "23"},{"first" : "Alice","last" :  "White","age":"24"}]
}

首先创建my_index索引,设置user的类型为nested,接着在查询时,需要通过es的nested查询语句查询,使用同样的方式查询first为John,last为White的用户,这次的结果是不存在。因为通过nested存储的对象是具有关联性的。

GET my_index/_search
{"query": {"nested": {"path": "user","query": {"bool": {"must": [{ "match": { "user.first": "John" }},{ "match": { "user.last":  "White" }} ]}}}}
}

上边的DSL语句用Java API实现如下:

@Test
public void testNested() throws Exception{//自己封装的一个获取RestHighLevelClient的类RestHighLevelClient client=ElasticSearchClient.getClient();SearchRequest request = new SearchRequest("my_index");SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();boolQueryBuilder.must(QueryBuilders.matchQuery("user.first","John"));boolQueryBuilder.must(QueryBuilders.matchQuery("user.last","White"));searchSourceBuilder.query(QueryBuilders.nestedQuery("user",boolQueryBuilder, ScoreMode.None));request.source(searchSourceBuilder);SearchResponse search = client.search(request, RequestOptions.DEFAULT);SearchHit[] hits = search.getHits().getHits();for (int i = 0; i < hits.length; i++) {SearchHit hit = hits[i];System.out.println(hit.getSourceAsString());}
}

(三)使用nested进行聚合查询

除了使用nested进行普通查询外,nested也支持聚合查询,同样是上面的例子,现在做一个对年龄聚合的操作:

GET my_index/_search
{"aggs": {"nestedAgg": {"nested": {"path": "user"},"aggs": {"ageAgg": {"terms": {"field": "user.age.keyword","size": 10}}}}}
}

(五)nested中的inner_hits

查询nested对象时,只要查询条件符合这个nested对象里的某一个条件,整个nested对象都会被检索出来。比如上面这个例子中,我只想查询叫做John Smith的这个人,但是通过普通的query查询会把整条记录都查询出来,效果就是这样:

"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_score" : 1.3862942,"_source" : {"group" : "fans","user" : [{"first" : "John","last" : "Smith","age" : "23"},{"first" : "Alice","last" : "White","age" : "24"}]}}]

如果只想要nested中里的一个对象,就可以使用inner_hits。使用比较简单,只需要在查询语句之后加上inner_hits即可。

GET my_index/_search
{"query": {"nested": {"path": "user","query": {"bool": {"must": [{ "match": { "user.first": "John" }},{ "match": { "user.last":  "Smith" }} ]}},"inner_hits": {}}}
}

查询结果里就会多出来一块数据,里面就只会展示具体的nested对象:

"inner_hits" : {"user" : {"hits" : {"total" : {"value" : 1,"relation" : "eq"},"max_score" : 1.3862942,"hits" : [{"_index" : "my_index","_type" : "_doc","_id" : "1","_nested" : {"field" : "user","offset" : 0},"_score" : 1.3862942,"_source" : {"last" : "Smith","first" : "John","age" : "23"}}]}}}

(六)nested的使用建议

nested可以很好地存储和查询对象类型数据,但是也不能滥用nested。每个nested对象都被索引为一个单独的文档,简单来讲就是如果一个索引里包含 100 个user对象,那么在实际底层将创建 101 个 Lucene 文档,是一个很大的消耗。

nested类型只应在特殊情况下使用,一个索引在创建的时候,nested类型的对象默认不能超过50个,可通过index.mapping.nested_fields.limit修改。

一个具体的文档中,nested类型中包含的嵌套对象的数量默认不能超过10000个,也就是说上面创建的user在一个文档里不能超过10000个,可通过index.mapping.nested_objects.limit修改。

深入了解ElasticSearch的Nested数据类型相关推荐

  1. Elasticsearch: object 及 nested 数据类型

    在处理大量数据时,关系数据库存在很多问题. 无论是速度,高效处理,有效并行化,可扩展性还是成本,当数据量开始增长时,关系数据库都会失败.该关系数据库的另一个挑战是必须预先定义关系和模式.Elastic ...

  2. Elasticsearch:高级数据类型介绍

    在我之前的文章 "Elasticsearch:一些有趣的数据类型",我已经介绍了一下很有趣的数据类型.在今天的文章中,我再进一步介绍一下高级的数据类型,虽然这里的数据类型可能和之前 ...

  3. Elasticsearch:Flattened 数据类型映射

    在本文中,我们将了解为了更好地处理包含大量或未知数量字段的文档而引入的 Elasticsearch 扁平化数据类型(flattened datatype). 默认情况下,Elasticsearch 会 ...

  4. ElasticSearch的Object数据类型

    上一篇mapping文章我们知道数字类型和日期类型要精确查找,以及mapping的两个重要的作用. 所以创建索引的时候,是不是可以预先定义字段的类型以及相关属性,这样就能够把日期字段处理成日期,把数字 ...

  5. Elasticsearch 嵌套类型nested

    1.背景介绍 我们在使用Elasticsearch做搜索引擎的时候有可能会遇到跨domain查询的场景,比如做一个学生课程管理系统,搜一个学生的名字,像知道该学生的选课情况. 当然解决问题的方法有很多 ...

  6. elasticsearch 基础 —— 字段数据类型

    核心数据类型(Core datatypes) 字符型(String datatype):string 数字型(Numeric datatypes):long, integer, short, byte ...

  7. Elasticsearch:flattened 数据类型 (7.3 发行版新功能)

    默认情况下,对象中的每个子字段都需要分别进行映射和索引.如果事先不知道子字段的名称或类型,则将动态映射它们. flattened 数据类型提供了一种替代方法,其中将整个对象映射为单个字段.对于给定的对 ...

  8. ElasticSearch系列03:ES的数据类型

    引言:上一节,我们学习了ES的基本概念和ES的数据架构[关注公众号:ZeroTeHero,获取上节内容].今天,TeHero将为大家讲解ES的数据类型. 数据的存储,都是需要预先确定好数据的类型的,不 ...

  9. Elasticsearch 对象及 Nested 对象【1】

    文章目录 1. 数据的关联关系 2. 关系型数据库的范式化设计 3. Denormalization 4. 在 Elasticsearch 中处理关联关系 5. 案例 1:博客和其作者信息 5.1 设 ...

  10. elasticsearch数据类型--join

    elasticsearch是一个搜索引擎,附带了数据存储功能.相比关系数据库为关系而生而言,elasticsearch并不删除处理数据之间的关系模型.但仍然提供了对此类需求的有限支持,join和nes ...

最新文章

  1. java linkedlist二维,如何在Java中制作二维LinkedList?
  2. java remote desktop_Remote Desktop
  3. 用户测评 | EDAS Serverless 上手体验 1
  4. 【链表】【树形DP】最大利润(jzoj 1487)
  5. 3位高二女生用大数据成功预测地铁出站人数 | 00后正在抛弃你
  6. 收藏 | 北大华为鹏城联合首次提出视觉 Transformer 后量化算法!
  7. 截取文件最后10行_10 行 Python 代码自动清理电脑内重复文件,解放双手
  8. java编程两个超长正整数相减_【每日编程237期】数字分类
  9. MySQL 磁盘满了,怎么办??
  10. 如何访问服务器表中信息,如何在 RADIUS 服务器的拨号接口上应用访问列表
  11. [c#]喜马拉雅FM音频批量下载器开发手记
  12. 基于激光雷达技术的3维虚拟校园建设与研究_爱学术—免费下载
  13. 开源的视频编解码器介绍
  14. 判断二极管导通例题_从120分到140分:高考数学解答题五大答题策略
  15. Cortex-M3技术参考手册 2022年3月1日
  16. qt类似电视盒子的通过方向键切换焦点的实现方法
  17. 苹果计算机密码bug,苹果iOS 13系统新BUG:快速输入密码,解锁无效
  18. Java必背基础词汇
  19. 【OS】Process Scheduling Synchronization
  20. win7驱动程序未经签名可以使用吗_windows-7 – Windows7引导选项,允许忽略未签名的驱动程序...

热门文章

  1. The Active Side of Stereopsis: Fixation Strategy and Adaptation to Natural Environments
  2. mysql mtq_第十六节:Mysql中的关键字
  3. google身份验证器
  4. 【开始报名】第二届中国移动“梧桐杯”大数据应用创新大赛邀你夺52w大奖
  5. 【Books系列】2021年:《断舍离》读书笔记
  6. 计算机连接不上蓝牙鼠标,蓝牙鼠标连接不上的解决方案
  7. java设置手机后台进程限制_当应用程序在Android Pie上受到后台限制时启动前台服务...
  8. 安卓实现图片缩放平移的基本步骤
  9. css淡入动画,使用CSS淡入大动画效果
  10. e4a怎么建立mysql_E4A编程MYSQL数据库操作