Elasticsearch中多索引数据合并与Nested嵌套类型操作全解析

发布于:2025-06-10 ⋅ 阅读:(23) ⋅ 点赞:(0)

多索引数据合并操作,以及嵌套类型(nested)的相关操作指南。

合并多索引数据到指定索引

现在需要将index_name-2025q1、index_name-2025q2、index_name-2025q3、index_name-2025q4这4个索引的数据合并到index_name-2025这一个索引里,可用如下操作

POST _reindex
{
  "source": {
    "index": "index_name-2025q*"
  },
  "dest": {
    "index": "index_name-2025"
  }
}

嵌套类型(nested)操作指南

一、数据结构说明

{
    "mappings": {
        "properties": {
	          "id": {
                "type": "keyword"
            },
            "orderId": {
                "type": "keyword"
            },
            "products": {
                "type": "nested",
                "properties": {
                  	"productName": {
                        "type": "text"
                    },
                    "productPrice": {
                        "type": "scaled_float",
                        "scaling_factor": 100
                    },
                    "productQuantity": {
                        "type": "integer"
                    }
                }
            }
        }
    }
}

这个数据结构里的products是一个典型的嵌套数据类型(nested)结构,包含了一个text类型的productName,浮点类型的productPrice和一个整数型的productQuantity。

二、基本CRUD操作

1. 插入文档
POST /your_index/_doc/1
{
	"id": 1,
  "orderId": "20250528000001",
  "products": [
    {
    	"productName": "手机",
      "productPrice": 5123.45,
      "productQuantity": 1
    },
    {
    	"productName": "钢化膜",
      "productPrice": 53.42,
      "productQuantity": 2
    }
  ]
}
2. 更新嵌套字段
POST /your_index/_update/1
{
  "script": {
    "source": """
      // 修改productName为'钢化膜'的记录的productPrice
      for(int i=0; i<ctx._source.products.length; i++) {
        if(ctx._source.products[i].productName == params.productName) {
          ctx._source.products[i].productPrice = params.productPrice;
          break;
        }
      }
    """,
    "params": {
      "productName": "钢化膜",
      "productPrice": 130.50
    }
  }
}
3. 删除嵌套数组中的特定元素
POST /your_index/_update/1
{
  "script": {
    "source": """
      // 删除productName为'钢化膜'的记录
      ctx._source.products.removeIf(item -> item.productName == params.productName);
    """,
    "params": {
      "productName": "钢化膜"
    }
  }
}

三、查询操作

1. 基础嵌套查询
GET /your_index/_search
{
  "query": {
    "nested": {
      "path": "products",
      "query": {
        "bool": {
          "must": [
            { "match": { "products.productName": "钢材" }},
            { "range": { "products.productPrice": { "gte": 100 }}}
          ]
        }
      }
    }
  }
}
2. 嵌套聚合分析
GET /your_index/_search
{
  "size": 0,
  "aggs": {
    "material_analysis": {
      "nested": {
        "path": "products"
      },
      "aggs": {
        "by_stuff": {
          "terms": {
            "field": "products.productName",
            "size": 10
          },
          "aggs": {
            "avg_fact": {
              "avg": {
                "field": "products.productPrice"
              }
            }
          }
        }
      }
    }
  }
}
3. 多条件嵌套查询
GET /your_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "products",
            "query": {
              "bool": {
                "must": [
                  { "term": { "products.productName": "手机" }},
                  { "range": { "products.productPrice": { "gt": 150 }}}
                ]
              }
            }
          }
        },
        {
          "match": { "otherField": "value" }
        }
      ]
    }
  }
}

四、特殊操作

1. 获取嵌套字段的内联命中
GET /your_index/_search
{
  "query": {
    "nested": {
      "path": "products",
      "query": {
        "match": { "products.productName": "钢化膜" }
      },
      "inner_hits": {}  // 获取匹配的嵌套对象
    }
  }
}
2. 嵌套排序
GET /your_index/_search
{
  "sort": [
    {
      "products.productPrice": {
        "order": "desc",
        "nested": {
          "path": "products",
          "filter": {
            "term": { "products.productName": "钢化膜" }
          }
        }
      }
    }
  ]
}

五、性能优化建议

  1. 合理设置 nested 字段数量 :嵌套文档会显著增加索引大小

  2. **使用 include_in_parent ** :如需频繁查询父文档字段

    "products": {
      "type": "nested",
      "include_in_parent": true,
      "properties": {...}
    }
    
  3. 控制嵌套文档大小 :单个文档的嵌套数组不宜过大(建议<100个元素)

  4. 使用 scaled_float 的优势 :比普通 float 更节省空间,适合有明确精度的数值