[ElasticSearch2.x]嵌套对象

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: 考虑到在Elasticsearch中创建,删除和更新的单个文档是原子操作的,因此在相同文档中存储紧密相关的实体是有意义的。 例如,我们可以在一个文档中存储一个订单和其所有的订单线(order lines),或者我们可以通过...

考虑到在Elasticsearch中创建,删除和更新的单个文档是原子操作的,因此在相同文档中存储紧密相关的实体是有意义的。 例如,我们可以在一个文档中存储一个订单和其所有的订单线(order lines),或者我们可以通过传递一组评论来将一篇博客文章及其所有评论存储在一起:

PUT /my_index/blogpost/1
{
  "title": "Nest eggs",
  "body":  "Making your money work...",
  "tags":  [ "cash", "shares" ],
  "comments": [ 
    {
      "name":    "John Smith",
      "comment": "Great article",
      "age":     28,
      "stars":   4,
      "date":    "2014-09-01"
    },
    {
      "name":    "Alice White",
      "comment": "More like this please",
      "age":     31,
      "stars":   5,
      "date":    "2014-10-22"
    }
  ]
}

如果我们依赖于动态映射,则comments字段将被自动映射为object字段。

因为所有的内容都在同一个文档中,所以没有必要在查询时把博客文章和评论进行连接查询,所以搜索效果很好。

问题是前面的文档会匹配一个这样的查询,查询名称为Alice年龄28岁:

GET /_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "comments.name": "Alice" }},
        { "match": { "comments.age":  28      }} 
      ]
    }
  }
}

输出结果:

{
    "title": "Nest eggs",
    "body": "Making your money work...",
    "tags": [
        "cash",
        "shares"
    ],
    "comments": [
        {
            "name": "John Smith",
            "comment": "Great article",
            "age": 28,
            "stars": 4,
            "date": "2014-09-01"
        },
        {
            "name": "Alice White",
            "comment": "More like this please",
            "age": 31,
            "stars": 5,
            "date": "2014-10-22"
        }
    ]
}

这与我们期望的不太一样,Alice31岁,而不是28岁,所以不应该返回上述结果.

如“内部数组”中讨论的,这种跨对象匹配的原因是,我们的JSON文档在索引中被扁平化为简单的键值格式,如下所示:

{
  "title":            [ eggs, nest ],
  "body":             [ making, money, work, your ],
  "tags":             [ cash, shares ],
  "comments.name":    [ alice, john, smith, white ],
  "comments.comment": [ article, great, like, more, please, this ],
  "comments.age":     [ 28, 31 ],
  "comments.stars":   [ 4, 5 ],
  "comments.date":    [ 2014-09-01, 2014-10-22 ]
}

Alice31岁之间的相关性,或John2014-09-01之间的相关性已经丢失了。 虽然object类型的字段(参见Multilevel Objects)对于存储单个对象很有用,但从搜索的角度来看,它们对于存储对象数组是无用的(While fields of type object are useful for storing a single object, they are useless, from a search point of view, for storing an array of objects)。

嵌套对象nested objects被设计来解决上述问题。通过将comments字段映射为nested而不是object,每个嵌套对象都将作为隐藏的单独文档hidden separate document进行索引,如下所示:

{ 
  "comments.name":    [ john, smith ],
  "comments.comment": [ article, great ],
  "comments.age":     [ 28 ],
  "comments.stars":   [ 4 ],
  "comments.date":    [ 2014-09-01 ]
}
{ 
  "comments.name":    [ alice, white ],
  "comments.comment": [ like, more, please, this ],
  "comments.age":     [ 31 ],
  "comments.stars":   [ 5 ],
  "comments.date":    [ 2014-10-22 ]
}
{ 
  "title":            [ eggs, nest ],
  "body":             [ making, money, work, your ],
  "tags":             [ cash, shares ]
}

通过分别索引每个嵌套对象,对象中的字段得以保持相关性。 如果匹配发生在同一个嵌套对象内,我们运行的查询才会匹配。

不仅如此,由于嵌套对象被索引的方式(嵌套文档直接存储在文档内部),在查询时将嵌套文档与根文档进行联合的速度几乎与查询单个文档一样快。

这些额外的嵌套文档是隐藏的; 我们无法直接访问它们。 要更新,添加或删除嵌套对象,我们必须重新索引整个文档。 请注意,搜索请求返回的结果不是单独的嵌套对象; 这是整个文件。

后面文章中我们会了解如何映射嵌套对象以及如何查询嵌套对象.

原文:https://www.elastic.co/guide/en/elasticsearch/guide/current/nested-objects.html

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
目录
相关文章
|
5月前
|
SQL 安全 数据挖掘
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
Elasticsearch聚合查询用于复杂数据分析,包括统计空值率。示例展示了如何计算字段`my_field`非空非零文档的百分比。查询分为三步:总文档数计数、符合条件文档数计数及计算百分比。聚合概念涵盖度量、桶和管道聚合。脚本在聚合中用于动态计算。常见聚合类型如`sum`、`avg`、`date_histogram`等。组合使用可实现多值统计、嵌套聚合和空值率计算。[阅读更多](https://zhangfeidezhu.com/?p=515)
297 0
Elasticsearch如何聚合查询多个统计值,如何嵌套聚合?并相互引用,统计索引中某一个字段的空值率?语法是怎么样的?
|
5月前
|
存储 索引
Elasticsearch索引之嵌套类型:深度剖析与实战应用
Elasticsearch索引之嵌套类型:深度剖析与实战应用
|
6月前
|
搜索推荐 JavaScript Java
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?
90 0
|
存储 JSON 数据建模
Elasticsearch数据建模实战之基于nested object实现博客与评论嵌套关系
Elasticsearch数据建模实战之基于nested object实现博客与评论嵌套关系
|
数据建模
白话Elasticsearch59-数据建模实战_ Nested Aggregation/ Reverse nested Aggregation对嵌套的博客评论数据进行聚合分析
白话Elasticsearch59-数据建模实战_ Nested Aggregation/ Reverse nested Aggregation对嵌套的博客评论数据进行聚合分析
93 0
|
存储 JSON 数据建模
白话Elasticsearch58-数据建模实战_基于nested object实现博客与评论嵌套关系
白话Elasticsearch58-数据建模实战_基于nested object实现博客与评论嵌套关系
78 0
|
数据挖掘 索引
白话Elasticsearch34-深入聚合数据分析之案例实战bucket嵌套实现颜色+品牌的多层下钻分析
白话Elasticsearch34-深入聚合数据分析之案例实战bucket嵌套实现颜色+品牌的多层下钻分析
105 0
|
Ubuntu Java 程序员
Elasticsearch聚合的嵌套桶如何排序
在elasticsearch的聚合查询中,经常对聚合的数据再次做聚合处理,这样的聚合结果如何进行排序呢,本文将对此展开讨论和实践
334 0
Elasticsearch聚合的嵌套桶如何排序
下一篇
无影云桌面