对象类型与嵌套类型

对象类型

JSON 字符串允许嵌套对象,一个文档可以嵌套多个、多层对象。

在创建mapping时,使用properties参数来指定对象的数据类型:

image-20220709191648711

由于 Lucene 并没有内部对象的概念,ES 会将原 JSON 文档扁平化存储,例如上面的对象类型,ES在索引时将其转换为”manufacture.name“, “manufacture.country” 这样扁平的key:

image-20220716210943758

查询时也可以使用这样的扁平key作为域来进行查询。


如果使用数组存储多个对象,在内部,Elasticsearch会将这些数组合并成一个Document:

image-20220709191858057

这种方式在查询时会遇到问题,例如我们查询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条件查询以下文档将不再返回结果:

image-20220716210837377

在内部,嵌套对象将数组中的每个对象索引为单独的隐藏文档,这意味着可以独立于其他对象查询每个嵌套对象。