深入理解Elasticsearch中的嵌套对象

Elasticsearch(简称ES)是一个基于Lucene的搜索引擎,它提供了全文搜索功能,而且也支持结构化数据的存储和查询。在ES中,嵌套对象(nested object)是一种特殊的数据结构,允许我们将多个文档存储在单个父文档中。这在处理具有复杂关系的数据时非常有用,例如订单和其包含的商品。

案例介绍

在这个案例中,我们将创建一个名为order-nested的索引,用于存储订单信息。每个订单包含一个或多个商品,这些商品以嵌套对象的形式存储在订单文档中。

创建索引和映射

首先,我们需要定义索引的映射,以指定每个字段的数据类型。特别是goods字段,我们将使用nested类型来定义它。

json 复制代码
PUT order-nested
{
  "mappings": {
    "properties": {
      "orderid": {
        "type": "integer"
      },
      "buyer": {
        "type": "keyword"
      },
      "order_time": {
        "type": "date",
        "format": "yyyy-MM-dd HH:mm:ss"
      },
      "goods": {
        "type": "nested",
        "properties": {
          "goodsid": {
            "type": "integer"
          },
          "goods_name": {
            "type": "keyword"
          },
          "price": {
            "type": "double"
          },
          "produce_time": {
            "type": "date",
            "format": "yyyy-MM-dd HH:mm:ss"
          }
        }
      }
    }
  }
}

添加文档

接下来,我们添加一个订单文档,包含两个商品。

json 复制代码
PUT order-nested/_doc/1
{
  "orderid": "1",
  "buyer": "tom",
  "order_time": "2020-11-04 00:00:00",
  "goods": [
    {
      "goodsid": "1",
      "goods_name": "milk",
      "price": 5.2,
      "produce_time": "2020-10-04 00:00:00"
    },
    {
      "goodsid": "2",
      "goods_name": "juice",
      "price": 8.2,
      "produce_time": "2020-10-12 00:00:00"
    }
  ]
}

更新文档

我们可以使用更新API来向订单中添加更多的商品。

json 复制代码
POST order-nested/_update/1
{
  "doc": {
    "goods": [
      {
        "goodsid": "3",
        "goods_name": "apple",
        "price": 18.2,
        "produce_time": "2020-10-05 00:00:00"
      }
    ]
  }
}

搜索和查询

使用嵌套查询,我们可以针对嵌套对象进行搜索。例如,我们可以找到所有包含特定商品名称和生产日期的订单。

json 复制代码
POST order-nested/_search
{
  "query": {
    "nested": {
      "path": "goods",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "goods.goods_name": "juice"
              }
            },
            {
              "match": {
                "goods.produce_time": "2020-10-04 00:00:00"
              }
            }
          ]
        }
      }
    }
  }
}

我们还可以在搜索结果中高亮显示匹配的嵌套字段。

json 复制代码
POST order-nested/_search
{
  "query": {
    "nested": {
      "path": "goods",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "goods.goods_name": "milk"
              }
            }
          ]
        }
      },
      "inner_hits": {
        "highlight": {
          "fields": {
            "*": {}
          }
        }
      }
    }
  }
}

排序和聚合

除了搜索,我们还可以对嵌套对象进行排序和聚合。例如,我们可以按照商品价格降序排序所有订单。

json 复制代码
POST order-nested/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "goods.price": {
        "order": "desc",
        "nested": {
          "path": "goods"
        },
        "mode": "sum"
      }
    }
  ]
}

或者,我们可以对商品名称进行聚合,以查看哪些商品名称最常见。

json 复制代码
POST order-nested/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "nest_agg": {
      "nested": {
        "path": "goods"
      },
      "aggs": {
        "items": {
          "terms": {
            "field": "goods.goods_name"
          }
        }
      }
    }
  }
}

结论

通过这个案例,我们可以看到Elasticsearch的嵌套对象功能如何帮助我们以一种非常灵活和强大的方式来处理和查询复杂的数据结构。嵌套对象不仅使得数据模型更加丰富,而且提供了强大的查询能力,使得我们可以轻松地执行复杂的搜索、排序和聚合操作。

相关推荐
大大大大晴天2 小时前
Flink CDC 深度解析:从原理到实践的全链路指南
大数据·flink
IT新视界3 小时前
Elasticsearch信创国产化替代
大数据·elasticsearch·搜索引擎
汇策研习社3 小时前
改良版ADX指标实战指南:告别传统ADX滞后、震荡误判难题
大数据·经验分享·金融·区块链·fastbull
SelectDB3 小时前
宽表元数据膨胀怎么解?Doris Segment V3 对比 Parquet、Lance
大数据·数据库·数据分析
隔窗听雨眠4 小时前
从追赶者到定义者:中国BI如何借助AI实现弯道超车
大数据·人工智能
cspttty4 小时前
二本软件工程专业好就业吗?毕业后能做哪些岗位
大数据·软件工程
智圣新创014 小时前
高校全域治理决策效能升级 智圣新创决策中台落地实操与行业趋势研判
大数据·人工智能·物联网
Elasticsearch5 小时前
用 Elasticsearch 的 RRF 融合检索,把矿物鉴定准确率从 36% 拉到 92%
elasticsearch
Elasticsearch5 小时前
景枢:基于 Elastic AI Agent Builder 的多景区购票智能运维中枢技术解析
elasticsearch
2401_859506245 小时前
玉石加工全链路技术变革:五大维度拆解材质改性、精密雕刻与智能溯源
大数据·人工智能