nested类型是一种特殊的对象object数据类型,允许对象数组彼此独立的进行索引和查询
_
对象数组如何扁平化
内部对象object字段的数组不能像我们所期望的那样工作。Lucene内部没有对象的概念,所以ES将对象层次结构扁平化为一个字段名称和值的简单列表:
PUT /my_index/_doc/1?pretty{"group": "fans","user": [{"first":"John", "last":"Smith"},{"first":"Alice", "last":"White"}]}
user字段被动态的添加为
object类型的字段,在其内部转化为一个看起来像下面这样的文档:
{"group":"fans","user.first":["John","Alice"],"user.last":["Smith","White"]}
user.first和user.last字段被扁平化为多值字段,并且alice和white质检的关联已经丢失。
以下文本文档将错误的匹配user.first和user.last为smith查询:
GET /my_indx/_doc{"query":{"bool":{"must":[{"match":{"user.first":"Alice"}},{"match":{"user.last":"Smith"}}]}}}//响应{"took": 2,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 0.5753642,"hits": [{"_index": "my_index","_type": "_doc","_id": "1","_score": 0.5753642,"_source": {"group": "fans","user": [{"first": "john","last": "smith"},{"first": "alice","last": "white"}]}}]}}
解释:可以看到,我们原本是想要查询用户名为Alice Smith的用户,实际文档中并不存在此用户,但是搜索还是错误的命中了此文档。
对对象数组使用嵌套字段
上面的例子描述了我们日常搜索的一些错误场景,但是我们要如何解决上面例子描述的问题呢?
如果需要索引对象数组并维护每个对象的独立性,则应对字段使用nested类型而不是使用object类型。
在内部,嵌套对象将数组中的每个对象作为单独的隐藏文档进行索引,这意味着每个嵌套对象都可以使用嵌套查询nested query独立于其他对象进行查询。
要实现netsted查询,我们首先要为文档设置正确的映射(mapping):
DELETE /my_indexPUT /my_index{"mappings": {"properties": {"user": {"type":"nested"}}}}PUT /my_index/_doc/1?pretty{"group": "fans","user": [{"first":"John", "last":"Smith"},{"first":"Alice", "last":"White"}]}
说明:此时user字段映射为nested类型,而不是默认的object类型
此时需要对bool查询进行一定的更改,再使用nested查询:
GET /my_index/_serach?pretty{"query": {"nested": {"path":"user","query": {"bool": {"must": [{"match":{"user.first":"Alice"}},{"match":{"user.last":"White"}},]}}}}}//响应{"took": 2,"timed_out": false,"_shards": {"total": 1,"successful": 1,"skipped": 0,"failed": 0},"hits": {"total": {"value": 1,"relation": "eq"},"max_score": 1.3862942,"hits": [{"_index": "my_index","_type": "_doc","_id": "1","_score": 1.3862942,"_source": {"group": "fans","user": [{"first": "John","last": "Smith"},{"first": "Alice","last": "White"}]}}]}}
可以发现。此时Alice White用户文档则被正确的命中。
