JSON 字符串允许嵌套对象,一个文档可以嵌套多个、多层对象。
在创建mapping时,使用properties
参数来指定对象的数据类型:
由于 Lucene 并没有内部对象的概念,ES 会将原 JSON 文档扁平化存储,例如上面的对象类型,ES在索引时将其转换为”manufacture.name“, “manufacture.country” 这样扁平的key:
查询时也可以使用这样的扁平key作为域来进行查询。
如果使用数组存储多个对象,在内部,Elasticsearch会将这些数组合并成一个Document:
这种方式在查询时会遇到问题,例如我们查询reviews.author =="John Doe" AND reviews.rating >= 4.0
, 会查询出两条数据——因为第一条满足rating >= 4.0
, 第二条满足reviews.author =="John Doe"
,而且在内部使用一个文档来存储。
这就引出了Nested Data Type
(嵌套数据类型)。
嵌套类型可以看成是一个特殊的对象类型,可以让对象数组独立检索。
针对上面的例子,我们可以将reviews
类型改成nested
:
PUT /products
{
"mappings": {
"properties": {
"name": {"type": "text"},
"reviews": {"type": "nested"}
}
}
}
此时使用reviews.author =="John Doe" AND reviews.rating >= 4.0
条件查询以下文档将不再返回结果:
在内部,嵌套对象将数组中的每个对象索引为单独的隐藏文档,这意味着可以独立于其他对象查询每个嵌套对象。