6.ELK之Elasticsearch嵌套(Nested)类型

这篇具有很好参考价值的文章主要介绍了6.ELK之Elasticsearch嵌套(Nested)类型。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0、前言

在Elasticsearch实际应用中经常会遇到嵌套文档的情况,而且会有“对象数组彼此独立地进行索引和查询的诉求”。在ES中这种嵌套文档称为父子文档,父子文档“彼此独立地进行查询”至少有以下两种方式:

1)父子文档。在ES的5.x版本中通过parent-child父子type实现,即一个索引对应多个type;

对于6.X+版本由于不再支持一个索引多个type,所以父子索引的实现改成了Join。

2)Nested嵌套类型。

参见官网:嵌套对象 | Elasticsearch: 权威指南 | Elastic

1、ES数据类型概览

1.常见类型
    binary:接受二进制值作为 Base64 编码的字符串。默认情况下,该字段不存储,也不可搜索,不能包含换行符 \n
    boolean:布尔类型,可以接受 true 或 false ,可以使用字符串和直接到布尔类型,空字符串为 false,包含:true,false,"true","false",""
    keyword:关键字类型,不进行分词,直接索引,支持模糊、支持精确匹配,支持聚合、排序操作,用于筛选数据。最大支持的长度为——32766 个 UTF-8 类型的字符。
    number:数字类型,文档链接
        long
        integer
        short
        byte
        double
        float
        half_float
        scaled_float
        unsigned_long

    Dates:日期类型
        date:可以是格式化后的日期字符串,也可以是时间戳,例如 2015-01-01, 2015-01-01T12:10:30Z,1420070400001
        date_nanos:支持纳秒的日期格式,在 es 内部是存的长整型
    alias :别名类型

2.对象和关系类型
    object:对象类型,是一个 json 对象
    flattened:将对象作为单个字段值存储
    nested:嵌套数据类型,可以看成是一个特殊的对象类型,可以让对象数组独立检索
    join:同一个文档,但具有父子关系的,类似于树
3.结构化数据类型
    range:范围类型,可以用来表示数据的区间
        integer_range
        float_range
        long_range
        double_range
        date_range
        ip_range

2、一个例子说明nested类型的作用

(1)Nested:嵌套对象是object数据类型的专用版本,能够对 对象数组进行彼此独立地索引和查询。

(2)对象数组默认组织形式

内部对象字段数组的实际存储机制与我们想的不一样。Lucene没有内部对象的概念,因为ElasticSearch将对象层次结构扁平化为一个字段名和字段值的列表。例如下面文档。

PUT user/user_info/1
{
  "group" : "man",
  "userName" : [ 
    {
      "first" : "张",
      "last" :  "三"
    },
    {
      "first" : "李",
      "last" :  "四"
    }
  ]
}

这里想要查询first为“张”,last为“四”的数据,按照我们的理解应该没有这种数据。按如下语句查询。

GET /user/user_info/_search
{
  "query":{
    "bool":{
        "must":[
            {
              "match":{
                "userName.first":"张"
              }
            },
            {
              "match":{
                "userName.last":"四"
              }
            }
         ]
    }
  }
}

查询结果如下:居然查询到了。这显然不符合我们的预期。

elasticsearch 嵌套类型,elk,elasticsearch,大数据

这个原因就是前面所说的lucene没有内部对象的概念,所谓的内部对象实际是被扁平化为一个简单的字段名称和值列表。文档内部存储是这个样子的:

{
  "group" :        "human",
  "sex" :          "man",
  "userName.first" : [ "张", "李" ],
  "userName.last" :  [ "三", "四" ]
}

显然 userName.first 和 userName.last 字段平面化为多值字段,之前的关联性丢失,查询就不会得到预期的结果。

那么要如何实现自己想要的语义呢? —— 显然就是本文想要说的nested了。

3、nested类型的使用

3.1、首先插入如下一条记录

其含义为博客文章信息数据,其中每篇文章的评论以comments字段数组存储。

PUT /financeblogs/blog/docidart1
{
  "title": "Invest Money",
  "body": "Please start investing money as soon...",
  "tags": ["money", "invest"],
  "published_on": "18 Oct 2017",
  "comments": [
    {
      "name": "William",
      "age": 34,
      "rating": 8,
      "comment": "Nice article..",
      "commented_on": "30 Nov 2017"
    },
    {
      "name": "John",
      "age": 38,
      "rating": 9,
      "comment": "I started investing after reading this.",
      "commented_on": "25 Nov 2017"
    },
    {
      "name": "Smith",
      "age": 33,
      "rating": 7,
      "comment": "Very good post",
      "commented_on": "20 Nov 2017"
    }
  ]
}

现在对于这条数据评论人姓名、年龄如下。

name age
William 34
John 38
Smith 33
3.2、非nested时内部对象无法按预期查询

我们尝试查询{name:John, age:34}评论过的博客,按照我们的理解应该没有符合条件的记录。但是由于前面说过的平铺的原因实际上如下查询语句是检索到这条数据了的。

GET /financeblogs/blog/_search
{
	"query":{
		"bool":{
			"must":[
				{
					"match":{
						"comments.name":"John"
					}
				},
				{
					"match":{
						"comments.age":"34"
					}
				}
			]
		}
	}
}
3.3、接下来换成nested的玩法

0.把这个索引删除再来一遍

DELETE financeblogs

1.创建如下索引。主要是mapping中的comments字段指定了类型为 nested。

PUT /financeblogs
{
  "mappings": {
    "blog": {
      "properties": {
        "title": {
          "type": "text"
        },
        "body": {
          "type": "text"
        },
        "tags": {
          "type": "keyword"
        },
        "published_on": {
          "type": "keyword"
        },
        "comments": {
          "type": "nested",
          "properties": {
            "name": {
              "type": "text"
            },
            "comment": {
              "type": "text"
            },
            "age": {
              "type": "short"
            },
            "rating": {
              "type": "short"
            },
            "commented_on": {
              "type": "text"
            }
          }
        }
      }
    }
  }
}

2.插入同样的目标数据

PUT /financeblogs/blog/docidart1
{
  "title": "Invest Money",
  "body": "Please start investing money as soon...",
  "tags": ["money", "invest"],
  "published_on": "18 Oct 2017",
  "comments": [
    {
      "name": "William",
      "age": 34,
      "rating": 8,
      "comment": "Nice article..",
      "commented_on": "30 Nov 2017"
    },
    {
      "name": "John",
      "age": 38,
      "rating": 9,
      "comment": "I started investing after reading this.",
      "commented_on": "25 Nov 2017"
    },
    {
      "name": "Smith",
      "age": 33,
      "rating": 7,
      "comment": "Very good post",
      "commented_on": "20 Nov 2017"
    }
  ]
}

3.使用nested查询方法

#查询name为John,age为34的记录发现是没有数据的。

GET /financeblogs/blog/_search?pretty
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "comments",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "comments.name": "John"
                    }
                  },
                  {
                    "match": {
                      "comments.age": 34
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

elasticsearch 嵌套类型,elk,elasticsearch,大数据

4.查询name为John,age为38的数据就是有的

elasticsearch 嵌套类型,elk,elasticsearch,大数据

4、父子和嵌套两种方式比对

嵌套(nested) 父子文档
优点

读取性能高

(据官方:比父子快5~10倍)

父子文档可以独立更新
缺点 更新子文档时需要更新整个文档

读取性能差,CPU占用率高

(需额外的内存去维护关系)

适应场景 查询为主,子文档偶尔更新的场景

子文档频繁更新;

子文档经常查询。

嵌套文档看似只是文档内有一个集合字段,但内部存储完全不是。以下图嵌套文档为例;留言1,留言2,留言3在内部实际存储为4个独立文档。

elasticsearch 嵌套类型,elk,elasticsearch,大数据

同时,嵌套文档的字段类型需要设置为nested。设置成nested后就不能被直接查询了,需要使用nested查询。

总结来说:

1.普通子对象默认实现了一对多的关系,会损失子对象的边界,子对象属性的关联性也会丧失。

2.嵌套(nested)对象可以解决普通子对象存在的问题,但是它有两个缺点:一是更新文档的时候要全部更新,另外就是不支持子文档从属多个主文档的场景。

3.父子文档能解决前面两个存在的问题,但是它适用于写多读少的场景(查询效率较慢)。

关于nested更多其他语法,参见:

干货 | Elasticsearch Nested类型深入详解_es nest类型-CSDN博客文章来源地址https://www.toymoban.com/news/detail-770463.html

到了这里,关于6.ELK之Elasticsearch嵌套(Nested)类型的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Elasticsearch多层嵌套nested查询和多条件聚合aggregations

     当在aggregations中使用嵌套多条件,需要用bool包起来,如果直接在filters[]里写,将会分多个桶,分别按单个条件统计;  部分片段截取: 当需要将多层嵌套nested用多个条件AND起来时: 全部片段: Elasticsearch 多层嵌套nested 多条件聚合aggregations

    2024年02月16日
    浏览(46)
  • ElasticSearch第五讲 ES nested嵌套文档与父子文档处理

    在ES中,处理实体之间的关系并不像关系型存储那样明显。在关系数据库中的黄金准则 - 数据规范化,在ES中并不适用。在处理关联关系,嵌套对象和父子关联关系中,我们会讨论几种可行方案的优点和缺点。 紧接着在为可扩展性而设计中,我们会讨论ES提供的一些用来快速灵

    2024年02月02日
    浏览(43)
  • 【ElasticSearch】ELK简介

    本文目录 一、什么是ELK? 二、ELK简介 2.1 E -- ElasticSearch 2.2 L -- Logstash 2.3 K -- Kibana 三、ELK优点 ELK 是 Elasticsearch 、 Logstash 、 Kibana 三大开源框架的首字母大写简称。市面上也被称为 Elastic Stack 。其中 Elasticsearch 是一个基于 Lucene 、 分布式 、 通过Restful方式 进行交互的 近实时搜

    2024年02月01日
    浏览(61)
  • 【ELK 学习】ElasticSearch

    ELK:ElasticSearch存储,Logstash收集,Kibana展示 版本较多,使用时需要版本匹配,还需要和mysql版本匹配(elastic官网给了版本对应关系) 本次使用的版本es6.8.12 filebeat 轻量级的数据收集工具 ElasticSearch为文档搜索产生的 分布式文档搜索,lucene单线程搜索的组合 ElasticSearch 除了j

    2024年02月01日
    浏览(38)
  • ElasticSearch 学习 ==ELK== 进阶

    (1)文档局部更新 我们也说过文档是不可变的——它们不能被更改,只能被替换。 update API必须遵循相同的规则。表面看来,我们似乎是局部更新了文档的位置,内部却是像我们之前说的一样简单的使用 update API处理相同的检索*- 修改 -*重建索引流程,我们也减少了其他进程

    2024年02月05日
    浏览(45)
  • ELK分析系统----Elasticsearch集群

    掌握Elasticsearch集群的简单使用 Elasticsearch:存储、搜索和分析 Elastcisearch是ELK核心的分布式搜索和引擎。logstash和beats有助于收集,聚合和丰富你的数据并将其存储在Elasticsearch中,使用kibana,可以交互式探索,可视化和共享对数据的见解,并管理和监视堆栈。Elasticsearch是发生

    2023年04月09日
    浏览(40)
  • ElasticSearch漫游 (1.安装ELK)

    前期准备: 请搭建好linux环境 推荐使用centos7系统 请关闭linux防火墙 请安装好docker 创建网络 我们需要部署kibana容器,因此需要让es和kibana互联,这里先创建一个网络。 加载es镜像 运行docker命令 部署单点es 命令解释: -e \\\"cluster.name=es-docker-cluster\\\" :设置集群名称 -e \\\"http.host=0.

    2024年02月09日
    浏览(43)
  • ELK 企业级日志分析系统的概念、ELK Elasticsearch 集群部署

    1、ELK 简介 ELK平台是一套完整的日志集中处理解决方案,将 ==ElasticSearch、Logstash 和 Kiabana ==三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ElasticSearch 是基于Lucene(一个全文检索引擎的架构)开发的分布式存储检索引擎,用来存储各类日志。 E

    2024年02月16日
    浏览(51)
  • ELK(ElasticSearch, Logstash, Kibana)

    ELK简介 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。 Elasticsearch是个开源分布式搜

    2023年04月09日
    浏览(51)
  • ELK入门(一)-Elasticsearch(docker版)

    Elasticsearch安装(docker) 下载Elasticsearch 查询镜像 拉取镜像 docker pull elasticsearch:版本号 · 挂载配置 创建挂载文件夹 修改文件夹权限 elasticsearch.yml 在config文件夹下创建elasticsearch.yml文件,并修改其为可读写执行权限。 修改elasticsearch.yml的内容 xpack.security.enabled: 配置es的安全,但是

    2024年02月21日
    浏览(50)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包