ES 中 Object 和 Nested 的区别

0. 提前剧透

Object 类型:扁平化存储,每个对象不单独存储,如果存储时是个数组,那么数组内的对象字段可能交叉匹配,导致匹配到错误结果,一般用在单层对象结构:如用户的地址信息(非数组),或者基本数据类型数组的场景。维护成本低。

Nested 类型:每个对象独立存储为隐藏的子文档,如果存储时是个数组,数组内的对象字段独立匹配,不会出现匹配错误的情况,一般用在es 某字段是个对象数组的场景,如订单中的商品列表、博客评论列表、线索跟进列表。插入和查询性能开销较大。

1. 核心区别

特性 object 类型 nested 类型
存储方式 扁平化存储,数组中的对象相同字段会合并成数组 每个对象独立存储为隐藏的子文档
查询准确性 数组内的对象字段可能交叉匹配(错误结果) 数组内的对象字段独立匹配(精确结果)
查询语法 普通 termmatch 查询 必须使用 nested 查询和 inner_hits
性能 高(无需额外维护子文档) 较低(需维护独立的子文档结构,写入和查询开销较高)
使用场景 单层对象结构:如用户的地址信息(非数组)。基本数据类型数组:字符串、整型数组,["tag1", "tag2"] 数组对象且需要数组对象需独立匹配:如订单中的商品列表、博客评论列表。
是否需要显示声明 否,当 Elasticsearch 检测到 JSON 数据中的对象(如 **{}**)或对象数组(如 **[{}, {}]**)时,默认会将其映射为 **object** 类型。 是,必须显式声明,因为它需要额外的存储和查询逻辑。

2. 数据示例对比

假设有一个 products 索引,存储商品信息,其中每个商品有多个供应商(名称和地区):

{
  "product": "Laptop",
  "suppliers": [
    { "name": "SupplierA", "region": "Asia" },
    { "name": "SupplierB", "region": "Europe" }
  ]
}
映射定义
  • object 类型(默认):
"mappings": {
  "properties": {
    "suppliers": { "type": "object" }
  }
}
  • nested 类型
"mappings": {
  "properties": {
    "suppliers": { "type": "nested" }
  }
}

3. 查询场景对比

场景:查找 region Asia name SupplierB 的供应商
  • object 类型查询
{
  "query": {
    "bool": {
      "must": [
        { "term": { "suppliers.name": "SupplierB" } },
        { "term": { "suppliers.region": "Asia" } }
      ]
    }
  }
}

结果:错误匹配到文档!原因object 类型将数组字段扁平化为 ["SupplierA", "SupplierB"]["Asia", "Europe"],导致跨对象匹配。

  • nested 类型查询
{
  "query": {
    "nested": {
      "path": "suppliers",
      "query": {
        "bool": {
          "must": [
            { "term": { "suppliers.name": "SupplierB" } },
            { "term": { "suppliers.region": "Asia" } }
          ]
        }
      }
    }
  }
}

结果:无匹配!原因nested 类型将每个供应商作为独立子文档处理,确保字段严格属于同一对象。

4. 适用场景

object 类型适用场景
  • 单层对象结构:如用户的地址信息(非数组)。
"address": {
  "street": "Main St",
  "city": "Beijing"
}
  • 无需精确匹配数组对象:如标签列表 ["tag1", "tag2"]
nested 类型适用场景
  • 数组对象需独立匹配:如订单中的商品列表、博客评论列表。
"orders": [
  { "product": "Keyboard", "price": 50 },
  { "product": "Mouse", "price": 30 }
]
  • 多条件关联查询:如“评论作者是 Alice 且评分大于 4 星”。

5. 性能注意事项

  • nested 类型:由于每个子文档独立存储,写入和查询开销较高,需谨慎设计 nested 层级。
  • 替代方案:若无需频繁查询嵌套字段,可使用 flattened 类型或父子文档(join)优化性能。这2种方案我还没试过。

你可能感兴趣的:(elasticsearch,大数据,搜索引擎,全文检索)