ES 中 Object 和 Nested 的区别
0. 提前剧透
Object 类型:扁平化存储,每个对象不单独存储,如果存储时是个数组,那么数组内的对象字段可能交叉匹配,导致匹配到错误结果,一般用在单层对象结构:如用户的地址信息(非数组),或者基本数据类型数组的场景。维护成本低。
Nested 类型:每个对象独立存储为隐藏的子文档,如果存储时是个数组,数组内的对象字段独立匹配,不会出现匹配错误的情况,一般用在es 某字段是个对象数组的场景,如订单中的商品列表、博客评论列表、线索跟进列表。插入和查询性能开销较大。
1. 核心区别
| 特性 | object 类型 | nested 类型 | 
|---|---|---|
| 存储方式 | 扁平化存储,数组中的对象相同字段会合并成数组 | 每个对象独立存储为隐藏的子文档 | 
| 查询准确性 | 数组内的对象字段可能交叉匹配(错误结果) | 数组内的对象字段独立匹配(精确结果) | 
| 查询语法 | 普通 term或match查询 | 必须使用 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种方案我还没试过。

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号