Elasticsearch 嵌套类型的深度剖析与实例


Elasticsearch 索引中的嵌套类型(Nested Types)是处理具有层次结构或一对多关系数据的有效工具。它允许在文档内部定义可以包含多个相同类型对象的数组,且这些内部对象可以独立地进行查询、过滤、排序和聚合。以下是关于 Elasticsearch 嵌套类型的深度剖析与实战应用:

嵌套类型的原理与特点

1. 原理:

  • 独立索引:嵌套对象在内部被当作独立的文档进行索引,这意味着每个嵌套对象都有自己的 _source_id 和元数据,并且拥有独立的 Lucene 文档(即一个分片)。

  • 父子关系模拟:虽然嵌套对象看起来像是父文档的一部分,但实际上它们与父文档之间是通过内部机制关联起来的。这种设计使得对嵌套对象的查询和更新不会影响到父文档的其他部分。

2. 特点:

  • 精准查询与过滤:嵌套查询允许对嵌套对象的属性进行精确匹配,不受父文档其他嵌套对象属性的影响。例如,可以查找特定用户的所有评论中包含特定关键词的那一条。

  • 独立排序与聚合:嵌套对象可以独立参与排序和聚合操作,这在分析数据时非常有用,比如统计每个用户的评论数量、计算特定产品类别的平均评分等。

  • 性能优化:与使用扁平化结构(如使用 object 类型)相比,嵌套类型在查询和聚合时通常更高效,因为它避免了“伪相关性”问题,即一个嵌套对象的属性值匹配导致整个父文档被视为匹配。

嵌套类型的创建与映射定义

在创建索引时,需要明确指定嵌套字段的类型为 nested。例如,在索引映射(mapping)中定义如下结构:

PUT my_index
{
  "mappings": {
    "properties": {
      "users": {
        "type": "nested",
        "properties": {
          "id": { "type": "keyword" },
          "name": { "type": "text" },
          "comments": {
            "type": "nested",
            "properties": {
              "id": { "type": "keyword" },
              "text": { "type": "text" },
              "rating": { "type": "integer" }
            }
          }
        }
      }
    }
  }
}

这里定义了一个 users 字段,其类型为 nested,内部包含 idname 以及另一个嵌套字段 commentscomments 字段同样为 nested 类型,包含 idtextrating 属性。

嵌套查询与过滤

使用 nested 查询 DSL 来针对嵌套对象进行精确查询和过滤。例如,查找某个用户的所有评论中评分大于 4 的评论:

GET my_index/_search
{
  "query": {
    "nested": {
      "path": "users.comments",
      "query": {
        "range": {
          "users.comments.rating": {
            "gte": 4
          }
        }
      }
    }
  }
}

嵌套聚合

在聚合阶段,可以使用 nested 聚合来对嵌套对象进行分组和统计。例如,统计每个用户评论的平均评分:

GET my_index/_search
{
  "aggs": {
    "user_ratings": {
      "nested": {
        "path": "users.comments"
      },
      "aggs": {
        "avg_rating": {
          "avg": {
            "field": "users.comments.rating"
          }
        }
      }
    }
  }
}

实战应用举例

电子商务场景

  • 商品评论分析:一个商品文档中包含一个评论数组,每个评论为一个嵌套对象,包含评论者信息、评论内容、评分等。可以轻松查询特定关键词出现在哪些评论中,或者按评分对评论进行排序和分页展示。

  • 用户购物车分析:用户文档中包含一个购物车数组,每个商品项为一个嵌套对象,包含商品ID、数量、添加时间等。可以快速统计用户的购物车中有多少种商品,或者分析购物车内商品的平均价格。

社交媒体场景

  • 帖子回复分析:一个帖子文档中包含一个回复数组,每个回复为一个嵌套对象,包含回复者信息、回复内容、点赞数等。可以高效地找出某用户的所有回复中被点赞最多的那个,或者统计某个话题下所有帖子的总回复数。

  • 用户关注关系:用户文档中包含一个关注者或被关注者数组,每个为一个嵌套对象,包含对方用户ID、关注时间等。可以轻松计算用户的粉丝数、好友数,或者找出用户最晚关注的那个人。

总之,Elasticsearch 的嵌套类型为处理具有嵌套结构的数据提供了强大而灵活的支持。通过精准查询、过滤和聚合,可以深入分析数据的内在关联和模式,为业务决策提供有力的数据支撑。在实际应用中,正确理解和运用嵌套类型能够显著提升检索性能和查询精度,特别是在处理复杂的一对多关系数据时。

Elasticsearch 嵌套类型的实例

以下是一个关于电子商务场景中使用 Elasticsearch 嵌套类型的实例,以商品评论数据为例进行说明。

场景描述

假设我们运营一个电商平台,每个商品文档包含多个用户评论。每个评论是一个嵌套对象,包含评论者ID、评论内容、评分、评论日期等信息。现在,我们需要根据用户的需求进行以下操作:

  1. 查找包含特定关键词的评论。
  2. 按评分对商品评论进行排序。
  3. 统计每个商品的平均评分。

索引与映射定义

首先,创建一个名为 product_reviews 的索引,并定义其映射,包含商品信息以及嵌套的评论数组:

PUT product_reviews
{
  "mappings": {
    "properties": {
      "product_id": {
        "type": "keyword"
      },
      "product_name": {
        "type": "text"
      },
      "reviews": {
        "type": "nested",
        "properties": {
          "reviewer_id": {
            "type": "keyword"
          },
          "content": {
            "type": "text"
          },
          "rating": {
            "type": "integer"
          },
          "date": {
            "type": "date"
          }
        }
      }
    }
  }
}

数据插入

向索引中插入几个商品及其评论示例数据:

POST product_reviews/_doc
{
  "product_id": "p001",
  "product_name": "Product A",
  "reviews": [
    {
      "reviewer_id": "u001",
      "content": "Great product! Highly recommended.",
      "rating": 5,
      "date": "202Ⅰ-01-01T00:00:00Z"
    },
    {
      "reviewer_id": "u002",
      "content": "Good quality, but slightly overpriced.",
      "rating": 4,
      "date": "202Ⅰ-02-15T00:00:00Z"
    }
  ]
}

POST product_reviews/_doc
{
  "product_id": "p002",
  "product_name": "Product B",
  "reviews": [
    {
      "reviewer_id": "u003",
      "content": "Not as described, disappointed.",
      "rating": 2,
      "date": "202Ⅰ-03-¾-01T00:00:00Z"
    },
    {
      "reviewer_id": "u004",
      "content": "Excellent value for money!",
      "rating": 5,
      "date": "202Ⅰ-04-15T00:00:00Z"
    }
  ]
}

实战应用

  1. 查找包含特定关键词的评论
GET product_reviews/_search
{
  "query": {
    "nested": {
      "path": "reviews",
      "query": {
        "match": {
          "reviews.content": "recommended"
        }
      }
    }
  }
}

此查询将返回包含关键词 “recommended” 的商品及其评论。

  1. 按评分对商品评论进行排序
GET product_reviews/_search
{
  "sort": [
    {
      "reviews.rating": {
        "order": "desc",
        "nested": {
          "path": "reviews"
        }
      }
    }
  ]
}

此查询将返回所有商品,按照评论的评分从高到低排序。

  1. 统计每个商品的平均评分
GET product_reviews/_search
{
  "size": 0,
  "aggs": {
    "products": {
      "terms": {
        "field": "product_id"
      },
      "aggs": {
        "average_ratings": {
          "nested": {
            "path": "reviews"
          },
          "aggs": {
            "avg_rating": {
              "avg": {
                "field": "reviews.rating"
              }
            }
          }
        }
      }
    }
  }
}

此聚合查询将返回每个商品的ID以及其平均评分。

以上实例展示了如何在实际的电子商务场景中使用 Elasticsearch 的嵌套类型进行数据建模、查询、排序和聚合操作,以满足对商品评论数据的各种分析需求。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

  • 26
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极致人生-010

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值