ElasticSearch之Nested对象

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

写在前面

本文看下es的nested嵌套对象相关内容。

1:es用了啥范式?

在关系型数据库中定义了6大数据库范式,即1,2,3,BC,4,5的NF(normal form),分别如下:

1NF:每个列都不可拆分,即都是原子的
2NF:在满足1NF的基础上,消除部分函数依赖
3NF:在满足2NF的基础上,消除传递函数依赖
BCNF:在满足3NF的基础上,消除主属性对于码的部分函数依赖和传递函数依赖(此时和非主键列没有关系)
4NF:在满足BCNF的基础上,消除表内的多对多关系
5NF:略

数据库范式的目的在于减少更新的复杂度,以及降低磁盘的存储空间。其中对于第二个问题存储设备目前非常廉价而且容量很大,所以不是什么问题了。对于第一个更新的复杂度问题会带来的查询效率变低的问题,因为需要更多的关联join。那么对于es来说它是使用了哪种范式呢?因为es的设计目标是快速查询,所以使用到是反范式,即冗余存储。比如如下的数据:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
如果按照关系型数据库范式来设计,user的信息需要存储到单独的一张表中去,但是在es中就是在一个对象中来存储,对于这种存储,es支持非常方便和高效的查询:

  • 准备数据
DELETE blog
# 设置blog的 Mapping
PUT /blog
{
  "mappings": {
    "properties": {
      "content": {
        "type": "text"
      },
      "time": {
        "type": "date"
      },
      "user": {
        "properties": {
          "city": {
            "type": "text"
          },
          "userid": {
            "type": "long"
          },
          "username": {
            "type": "keyword"
          }
        }
      }
    }
  }
}


# 插入一条 Blog 信息
PUT blog/_doc/1
{
  "content":"I like Elasticsearch",
  "time":"2019-01-01T00:00:00",
  "user":{
    "userid":1,
    "username":"Jack",
    "city":"Shanghai"
  }
}
  • 查询
# 查询 Blog 信息
POST blog/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"content": "Elasticsearch"}},
        {"match": {"user.username": "Jack"}}
      ]
    }
  }
}

ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
我们再来看一个存储对象数组的例子:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式

  • 准备数据
DELETE my_movies

# 电影的Mapping信息
PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "properties" : {
            "first_name" : {
              "type" : "keyword"
            },
            "last_name" : {
              "type" : "keyword"
            }
          }
        },
        "title" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
}


# 写入一条电影信息
POST my_movies/_doc/1
{
  "title":"Speed",
  "actors":[
    {
      "first_name":"Keanu",
      "last_name":"Reeves"
    },

    {
      "first_name":"Dennis",
      "last_name":"Hopper"
    }

  ]
}
  • 查询first_name为Keanu并且last_name为Hopper的文档信息
POST my_movies/_search
{
  "query": {
    "bool": {
      "must": [
        {"match": {"actors.first_name": "Keanu"}},
        {"match": {"actors.last_name": "Hopper"}}
      ]
    }
  }

}

ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
按照正常思维,应该查不到才对,但为什么查到了呢?这和es的数据存储方式有关系,对于数组es默认是按照一种扁平结构来存储的,如下:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
这种存储结构的好处是可以加快查询的速度,但坏处呢就是上例中反直觉结果。

所以如果能够让内部的对象也按照单独文档来存储,就能解决这个查询错误的问题了,而想要使用单独的文档来存储内部的对象,就需要用到es提供的nested对象功能,继续来看(作为本文的主题,必须单开一部分,还必须是一级标题😀😀😀)

2:nested对象

nested是一种定义对象的数据类型,比如可通过如下方式来定义一个nested的类型:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
在保存时会被保存为单独的文档,查询时通过join的方式来查询,当然此时会牺牲掉部分查询性能。

  • 创建如下的mapping
DELETE my_movies
# 创建 Nested 对象 Mapping
PUT my_movies
{
      "mappings" : {
      "properties" : {
        "actors" : {
          "type": "nested",
          "properties" : {
            "first_name" : {"type" : "keyword"},
            "last_name" : {"type" : "keyword"}
          }},
        "title" : {
          "type" : "text",
          "fields" : {"keyword":{"type":"keyword","ignore_above":256}}
        }
      }
    }
}
  • 接着来插入测试数据
POST my_movies/_doc/1
{
  "title":"Speed",
  "actors":[
    {
      "first_name":"Keanu",
      "last_name":"Reeves"
    },

    {
      "first_name":"Dennis",
      "last_name":"Hopper"
    }

  ]
}

此时存储结构为红框中所示:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式

  • 查询first_name为Keanu并且last_name为Hopper的文档信息
    此时就查询不到了:
POST my_movies/_search
{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "path": "actors",
                        "query": {
                            "bool": {
                                "must": [
                                    {
                                        "match": {
                                            "actors.first_name": "Keanu"
                                        }
                                    },
                                    {
                                        "match": {
                                            "actors.last_name": "Hopper"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            ]
        }
    }
}

ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式
当然如果把"actors.last_name": "Hopper"改为Reeves是能查出来数据的:
ElasticSearch之Nested对象,ElasticSearch,elasticsearch,nested对象,数据库范式,反范式

写在后面

参考文章列表

关系型数据库MySQL及其优化 。文章来源地址https://www.toymoban.com/news/detail-844111.html

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

原文地址:https://blog.csdn.net/wang0907/article/details/136706315

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

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

相关文章

  • Elasticsearch:如何修改 nested 字段的值

    Nested 类型是 object 数据类型的特殊版本,它允许对象数组以一种可以彼此独立查询的方式进行索引。在内部,嵌套对象将数组中的每个对象索引为单独的隐藏文档,这意味着每个嵌套对象都可以使用 nested query 独立于其他对象进行查询。每个 nested 对象都被索引为一个单独的

    2024年02月14日
    浏览(13)
  • 6.ELK之Elasticsearch嵌套(Nested)类型

    在Elasticsearch实际应用中经常会遇到嵌套文档的情况,而且会有“对象数组彼此独立地进行索引和查询的诉求”。在ES中这种嵌套文档称为父子文档,父子文档“彼此独立地进行查询”至少有以下两种方式: 1)父子文档。在ES的5.x版本中通过parent-child父子type实现,即一个索引

    2024年02月03日
    浏览(11)
  • Elasticsearch多层嵌套nested查询和多条件聚合aggregations

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

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

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

    2024年02月02日
    浏览(15)
  • Elasticsearch 基于 array 结构 的nested类型的索引的聚合查询

    这几天在做es的聚合查询,对那种一对多的产品数据查询的时候遇到了一些问题,做一下记录 针对每个产品名称[ product_name ]进行分组,并对预算[ budget ]求和 产品名称 预算 电视机 4000 手机 851 相机 5000 扑克牌 2 es查询语句==简化版 es查询的结果==简化版 注意电视机的doc_count为

    2024年02月16日
    浏览(16)
  • Elasticsearch中object类型与nested类型以及数组之间的区别

    0、一般情况下用object 类型来查es中为json对象的字段数据,用nested来查es中为JsonArray数组类型的字段数据。 1、默认情况下ES会把JSON对象直接映射为object类型,只有手动设置才会映射为nested类型 2、object类型可以直接使用普通的逗号(.)查询,比如 3、nested类型的查询需要使用

    2024年01月22日
    浏览(19)
  • Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?

    这是来自社区的一个真实企业场景问题。 https://elasticsearch.cn/question/13135 如下所示, 希望在查出的结果后, 对结果进行后处理,对tags列表,根据depth进行排序。 Elasticsearch 能支持的排序方式罗列如下: 包含但不限于: 基于特定字段的排序 基于Nested对象字段的排序 基于特定

    2024年02月02日
    浏览(15)
  • 数据库报错 Failed to obtain JDBC Connection; nested exception is java.sql.SQLException: Access denied

    如果你也是用Java连接数据库的可以尝试看看 第一种类型 如果是MySQL8.0以上的,需要在后面加上 如果是这种的错误类型的,可以试试 第二种类型 数据库没有设置开放权限,不给连接,这种情况就算是使用连接数据库工具也没办法连接的。解决方式如下 第三种类型 这种如果是

    2024年01月24日
    浏览(10)
  • clickhouse的嵌套数据结构Tuple、Array与Nested类型介绍和使用示例

    Tuple 是 ClickHouse 数据库中的一种数据类型,它允许在一个字段中存储由不同数据类型组成的元组(tuple)。 元组可以包含任意数量的值,并且每个值可以是不同的数据类型,如 int 、 float 、 string 、 date 等。 例如,以下是一个 clickhouse Tuple 类型的例子: (1, \\\'John\\\', 12.5, Date(\\\'2021-0

    2024年02月14日
    浏览(8)
  • Elasticsearch 对比传统数据库:深入挖掘 Elasticsearch 的优势

    当你为项目选择数据库或搜索引擎时,了解每个选项的细微差别至关重要。 今天,我们将深入探讨 Elasticsearch 的优势,并探讨它与传统 SQL 和 NoSQL 数据库的比较。 Elasticsearch 以强大的 Apache Lucene 库为基础,是一个分布式搜索和分析引擎。 它以其速度、可扩展性以及快速索引

    2024年02月10日
    浏览(8)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包