Elasticsearch之Nested Object

翻译 2015年04月14日 16:46:18

                                 (这是一个小系列:请戳:ElasticsearchNested(嵌套)系列,查看其他nested相关文章)

   Given the fact that creating, deleting, and updating a single document in Elasticsearch is atomic, 

it makes sense to store closely related entities within the same document.

考虑到在ES里面建立,删除和更新一个单一文本是原子性的,那么将相关实体保存在同一个文本里面是有意义的。

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"
     }
  ]
}

Because all of the content is in the same document, there is no need to join blog posts and comments at query time, so searches perform well. 

因为所有的内容都在同一文本里面,在查询的时候就没有必要拼接blog posts,因此检索性能会更好。

The problem is that the preceding document would match a query like this: 

问题是,上面的文档会匹配这样的一个查询:

curl -XPGET 'localhost:9200/_search' -d '
{
  "query":{
     "bool":{
   "must":[
     {"match":{"name":"Alice"}},
     {"match":{"age":28}}
   ]
 }
  }
}'
但是Alice is 31,不是28啊!

The reason for this cross-object matching, as discussed in Arrays of Inner Objects, is that our beautifully structured JSON document is flattened into a simple key-value format in the index that looks like this:

造成这种交叉对象匹配是因为结构性的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 ]
}

The correlation between Alice and 31, or between John and 2014-09-01, has been irretrievably lost. 

显然,像这种‘Alice/31’,‘john/’2014-09-01’间的关联性就不可避免的丢失了。

While fields of type object (see Multilevel Objects) are useful for storing a single object, they are useless, from a search point of view, 

for storing an array of objects.

虽然object类型的字段对于保存一个单一的object很有用,但是从检索的角度来说,这对于保存一个object数组却是无用的。

This is the problem that nested objects are designed to solve。

nested object就是为了解决上述问题而设计出来的。

By mapping the commments field as type nested instead of type object, each nested object is indexed as a hidden separate document, something like this:

通过将comments字段映射为nested类型,而不是object类型,每一个nested object 将会作为一个隐藏的单独文本建立索引。如下:

{ ①
  "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 ]
}
①nested object

By indexing each nested object separately, the fields within the object maintain their relationships. We can run queries that will match only 

if the match occurs within the same nested object.

通过分开给每个nested object建索引,object内部的字段间的关系就能保持。当执行查询时,只会匹配’match’同时出现在相同的nested object的结果.

Not only that, because of the way that nested objects are indexed, joining the nested documents to the root document at query time is fastalmost as fast as if they were a single document.

不仅如此,由于nested objects 建索引的方式,在查询的时候将根文本和nested文档拼接是很快的,就跟把他们当成一个单独的文本一样的快。

These extra nested documents are hidden; we cant access them directly. To update, add, or remove a nested object, we have to reindex 

the whole document. Its important to note that, the result returned by a search request is not the nested object alone; it is the whole document.

这些额外的nested文本是隐藏的;我们不能直接接触。为了更新,增加或者移除一个nested对象,必须重新插入整个文本。要记住一点:查询请求返回的结果不仅仅包括nested对象,而是整个文本。

You may want to index inner objects both as nested fields and as flattened object fields, eg for highlighting. This can be achieved

 by setting include_in_parent to true:

你可能想要检索内部object同时当作nested 字段和当作整平的object字段,比如为了强调。这可以通过将include_in_parent设置为true实现:

curl -XPUT 'localhost:9200/my_index' -d '
{
  "mappings":{
     "blogpost":{
	     "properties":{
		     "comments":{
			    "type":"nested",
				"include_in_parent":true,
				"properties":{
				   "name":    {"type":"string"    },
				   "comment": { "type": "string"  },
                   "age":     { "type": "short"   },
                   "stars":   { "type": "short"   },
                   "date":    { "type": "date"    }
				}
			 }
		 }
	 }
  }
}

The result of indexing our example document would be something like this:

查询结果类似这样:

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

Nested fields may contain other nested fields. The include_in_parent object refers to the direct parent of the field, while the include_in_root 

parameter refers only to the topmost “root” object or document.

nested 字段可能会包含其他的nested 字段。include_in_parent object关联字段的直接上层,而include_in_root仅仅关联“根”obejct或文本



参考:

1.http://www.elastic.co/guide/en/elasticsearch/guide/master/nested-objects.html

2.http://www.elastic.co/guide/en/elasticsearch/reference/1.4/mapping-nested-type.html



EJB商业探讨的白皮书

1 业界支持  任何一个商业化的技术要想拥有良好的市场态势,业界内重要企业的大量参与是十分重要的。J2EE是由SUN引导,各厂商共同发起的,并得到广泛认可的工业标准。业内企业计算领域的大企业如:IBM...
  • DrunkenLion
  • DrunkenLion
  • 2001-06-20 08:49:00
  • 664

Elasticsearch嵌套式对象Nested分析

nested结构是Elasticsearch提供关系存储的一种特殊的结构,是NOSQL的一种高级特性,在传统的关系型sql中,很难做到一行记录中存储某个实体以及附属的内容,比如某个用户下评论数据,或某...
  • u012332735
  • u012332735
  • 2017-03-15 14:13:12
  • 10338

Elasticsearch之Nested Aggregation

(这是一个小系列:请戳:Elasticsearch之Nested(嵌套)系列,查看其他nested相关文章)              In the same way as we need to u...
  • Allenalex
  • Allenalex
  • 2015-04-16 20:52:07
  • 6101

ES中更新一个nested字段的结构

与更新普通object字段相类似,更新nested字段只需加上type类型就可以了,例如要在tags_list这个nested字段中加入ratio字段,我们只需这样写代码即可 add_body = ...
  • yyd19921214
  • yyd19921214
  • 2017-03-02 11:21:26
  • 1087

为什么ES不适合做数据存储

前段时间公司想尝试用ES来存一部分数据,以此缓解数据增长带来的对数据库的压力。ES的介绍很多地方都有,就不再写了。在研究了一段时间后,发现ES不适合做为数据存储使用,理由如下: mapping不可改...
  • wzdxt
  • wzdxt
  • 2016-03-20 14:43:54
  • 13085

Elasticsearch学习方法以及复杂数据类型的映射

Elasticsearch学习方法、环境搭建以及复杂数据类型的映射。
  • YQS_Love
  • YQS_Love
  • 2017-04-24 10:56:38
  • 2169

Elasticsearch Java API(八)--搜索有相同父id的子文档

需求: 搜索具有相同父id的所有子文档. 数据:    mapping:      { "mappings": { "branch": {}, "emplo...
  • napoay
  • napoay
  • 2016-08-04 13:40:50
  • 4971

Elasticsearch nested sort filter 嵌套排序问题及解决

官方解释首先来看一下官方文档:Sorting by Nested Fields 看不懂的没关系,它其实就只有两句是有用的,就是那两段代码。索引PUT /my_index/blogpost/2 { ...
  • zhanlanmg
  • zhanlanmg
  • 2015-10-20 20:02:10
  • 9892

ElasticSearch聚合查询小例子

在ES里面所有的聚合实例都由AggregationBuilders类提供静态方法构造,我们先看下常用有哪些方法使用: (1)统计某个字段的数量 ValueCountBuilder vcb= Ag...
  • u010454030
  • u010454030
  • 2017-03-18 19:39:58
  • 4092

elasticsearch之mapping配置

序 本文主要记录es的schema mapping的一些配置项 mapping定义 { "mappings": { "post": { "properties": { ...
  • u012450329
  • u012450329
  • 2016-09-20 22:09:34
  • 5189
收藏助手
不良信息举报
您举报文章:Elasticsearch之Nested Object
举报原因:
原因补充:

(最多只允许输入30个字)