Elasticsearch之Nested Object

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 fast—almost as fast as if they were a single document.

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

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

the whole document. It’s 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

时间: 2024-08-03 00:11:56

Elasticsearch之Nested Object的相关文章

Elasticsearch之Nested Object Mapping

Setting up a nested field is simple-where you would normally specify type object, make it type nested instead: 创建一个nested 字段很简单--只要在你通常指定object类型的地方,改成nested类型就行: curl -XPUT 'localhost:9200/my_index' -d ' { "mappings":{ "blogpost":{ &q

Elasticsearch之Nested(嵌套)系列

工作需要,专门花了一下午研究了Elasticsearch里面的nested.最好的材料还是官网上面的Elasticsearch: The Definitive Guide, 所以直接将里面涉及到nested的文章找来看了看,顺便把它们翻译了,贴出来和大家分享.同时综合考虑了一下,把英语大体的 英文原文也一起贴出来了.希望这样能够适应不同读者的口味. 文章都顺手翻译了,每天贴出来一篇吧. 1.Elasticsearch之Nested Object 2.Elasticsearch之Nested Ob

Elasticsearch之Nested Aggregation

(这是一个小系列:请戳:Elasticsearch之Nested(嵌套)系列,查看其他nested相关文章) In the same way as we need to use the special nested query to gain access to nested objects at search time, the dedicated nested aggregation allows us to aggregate fields in nested objects: 与在检索时

Elasticsearch之Nested Sorting

(这是一个小系列:请戳:Elasticsearch之Nested(嵌套)系列,查看其他nested相关文章) It is possible to sort by the value of a nested field, even though the value exists in a separate nested document. To make the result more interesting, we will add another record: 尽管存在于独立的nested文

ElasticSearch 基础(4) - Mapping

一.Mapping概述 为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成Full-text或者精确的字符串值. ES需要知道每个字段里面都包含了什么类型.这些类型和字段的信息存储(包含)在映射(mapping)中. 索引中每个文档都有一个类型(type).每个类型都拥有自己的映射(mapping)或者模式定义(schema definition). 一个映射定义了字段类型,每个字段的数据类型,以及字段被Elasticsearch处理的方式.映射还用于设置关联到类型上的元数据

elasticsearch按照配置时遇到的一些坑 [Failed to load settings from [elasticsearch.yml]]

这里整理几个空格引起的问题. 版本是elasticsearch-2.3.0 或者elasticsearch-rtf-master Exception in thread "main" SettingsException[Failed to load settings from [elasticsearch.yml]]; nested: ElasticsearchParseException[malformed, expected settings to start with 'obje

elasticsearch 映射规则

Mapping简述 Elasticsearch是一个schema-less的系统,但并不代表no shema,而是会尽量根据JSON源数据的基础类型猜测你想要的字段类型映射.Elasticsearch中Mapping类似于静态语言中的数据类型,但是同语言的数据类型相比,映射还有一些其他的含义.Elasticsearch会根据JSON源数据的基础类型猜测你想要的字段映射.将输入的数据转变成可搜索的索引项.Mapping就是我们自己定义的字段的数据类型,同时告诉Elasticsearch如何索引数据

ElasticSearch 嵌套映射和过滤器及查询

ElasticSearch - 嵌套映射和过滤器 Because nested objects are indexed as separate hidden documents, we can’t query them directly. Instead, we have to use the nested query to access them: GET /my_index/blogpost/_search { "query": { "bool": { &quo

Query DSL for elasticsearch Query

Query DSL Query DSL (资料来自: http://www.elasticsearch.cn/guide/reference/query-dsl/) http://elasticsearch.qiniudn.com/ --简介-- elasticsearch 提供基于JSON的完整的Query DSL查询表达式(DSL即领域专用语言). 一般来说, 普通的查询如 term 或者 prefix. 另外还有混合查询如 bool 等. 另外查询表达式(Queries)还能够关联特定的过