Elasticsearch : array of innner object vs. nested object

       为了克服Arrays of Inner Objects 扁平化内部对象而丢失对象内部数据之间的关联信息的不足,Elasticsearch提供了Nested object。Nested object把每个内部对象做为一个独立的隐藏文件存储,从而保存了对象之间的独立性。对于nested object搜索,Elasticsearch也提供专门的搜索语法 -Querying a Nested Object。通过下面的例子,大家可以体会一下nested object和array of inner objects的区别:


(1)  索引一个包含两个内部对象的文档,默认情况下,Elasticsearch会使用array of inner object方式为他们创建mapping并进行索引。

PUT /testindex/object/1
{
   "binaries": [
      {
         "extension": "pptx",
         "description": "fancy presentation",
         "size": 999
      },
      {
         "extension": "pdf",
         "description": "fancy presentation for all to read",
         "size": 10
      }
   ]
}


(2) 查看一下Elasticsearch为其创建的mapping。

{
   "testindex": {
      "mappings": {
         "object": {
            "properties": {
               "binaries": {
                  "properties": {
                     "description": {
                        "type": "string"
                     },
                     "extension": {
                        "type": "string"
                     },
                     "size": {
                        "type": "long"
                     }
                  }
               }
            }
         }
      }
   }
}


(3) 接下来我们搜索一下包括 extersion = pptx 同时 size<100 binary对象的文档。  

GET /testindex/object/_search
{
   "query": {
      "filtered": {
         "filter": {
            "bool": {
               "must": [
                  {
                     "term": {
                        "extension": "pptx"
                     }
                  },
                  {
                     "range": {
                        "size": {
                           "lte": 100
                        }
                     }
                  }
               ]
            }
         }
      }
   }
}


(4) 当前索引中只包含一个文档,我们可以清楚看到该文档并不包含extersion = pptx 同时 size<100 的binary对象。可是搜索结果仍然返回了一个结果,有些出人意料哦!这正是array of inner object确定,因为inner object的结构被扁平化存储,所以搜索是在横过了多个inner objects进行的。

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 2,
      "successful": 2,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "testindex",
            "_type": "object",
            "_id": "1",
            "_score": 1,
            "_source": {
               "binaries": [
                  {
                     "extension": "pptx",
                     "description": "fancy presentation",
                     "size": 999
                  },
                  {
                     "extension": "pdf",
                     "description": "fancy presentation for all to read",
                     "size": 10
                  }
               ]
            }
         }
      ]
   }
}


(5)接下来我们来看看nestedobject是如何解决这个问题的,首先创建一个专门的nestedobject设计的mapping:

PUT /testindex/_mapping/nestedobject
{
   "nestedobject": {
      "properties": {
         "binaries": {
            "type": "nested",
            "properties": {
               "extension": {
                  "type": "string"
               },
               "description": {
                  "type": "string"
               },
               "size": {
                  "type": "long"
               }
            }
         }
      }
   }
}


(6) 索引一个和之前的一样的文档:

PUT /testindex/nestedobject/2
{
   "binaries": [
      {
         "extension": "pptx",
         "description": "fancy presentation",
         "size": 999
      },
      {
         "extension": "pdf",
         "description": "fancy presentation for all to read",
         "size": 10
      }
   ]
}


(7) 再用nested query来一把同样搜索条件的搜索吧。真神奇啊,没有任何结果返回,哈哈哈!这就是nested object.

GET /testindex/nestedobject/_search
{
   "query": {
      "filtered": {
         "filter": {
            "nested": {
               "path": "binaries",
               "filter": {
                  "bool": {
                     "must": [
                        {
                           "term": {
                              "extension": "pptx"
                           }
                        },
                        {
                           "range": {
                              "size": {
                                 "lte": 100
                              }
                           }
                        }
                     ]
                  }
               }
            }
         }
      }
   }
}


鱼和熊掌可皆得吗? 当然。如果你既需要nested object同时也要扁平的object,在mapping中加入 include_in_parent即可,如下所示:

PUT /testindex/_mapping/nestedobject
{
   "nestedobject": {
      "properties": {
         "binaries": {
            "type": "nested",
            "include_in_parent": true,
            "properties": {
               "extension": {
                  "type": "string"
               },
               "description": {
                  "type": "string"
               },
               "size": {
                  "type": "long"
               }
            }
         }
      }
   }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值