Elasticsearch(简称ES)是一个基于Lucene的全文搜索引擎,它提供了强大的搜索能力以及对数据的高效索引和查询。在ES中,数据通常以JSON格式存储,并且可以采用多种数据类型。其中,nested
类型是一种特殊的对象数组类型,它允许我们以一种可以独立查询的方式存储和索引对象数组。本文将详细介绍nested
类型的概念、作用、适用场景以及如何通过DSL和API进行增删改查和聚合操作。
环境准备
在开始之前,请确保你的Elasticsearch服务已启动,并且你已经熟悉基本的Elasticsearch操作。本文示例基于Elasticsearch 6.X版本。
Nested类型概述
nested
类型是专为对象数组设计的,它允许数组中的每个对象作为一个独立的文档进行索引,从而可以独立于其他对象进行查询。这在处理具有复杂嵌套结构的数据时非常有用,例如一个博客文章及其评论。
适用场景
- 当你需要对数组中的每个元素进行独立查询时。
- 当数组元素具有自己的字段,并且这些字段需要被单独索引和搜索时。
Nested类型的增删改查与聚合操作
1. 增加(Insert)
假设我们有一个博客文章,它包含多个评论。我们可以使用以下DSL来增加一个新文档:
json
POST /blog/_doc/1
{
"title": "Elasticsearch Nested类型详解",
"body": "本文详细介绍了Elasticsearch中的nested类型...",
"comments": [
{
"name": "John",
"comment": "非常好的文章,学习了很多!",
"age": 28
},
{
"name": "Doe",
"comment": "感谢分享,期待更多内容。",
"age": 32
}
]
}
2. 删除(Delete)
如果我们想删除特定用户的评论,可以使用以下API:
json
POST /blog/_update/1
{
"script": {
"source": "ctx._source.comments.removeIf(c -> c.name == 'John')"
}
}
3. 修改(Update)
要更新某个用户的评论内容和年龄,可以这样做:
json
POST /blog/_update/1
{
"script": {
"source": "for (def c : ctx._source.comments) { if (c.name == 'Doe') { c.comment = '更新后的评论内容'; c.age = 33; }}"
}
}
4. 查询(Search)
使用nested
查询来找到特定用户的所有博客文章:
json
GET /blog/_search
{
"query": {
"nested": {
"path": "comments",
"query": {
"bool": {
"must": [
{ "match": { "comments.name": "John" }}
]
}
}
}
}
}
5. 聚合(Aggregation)
我们可以对评论者的年龄进行聚合,找出最小的年龄:
json
GET /blog/_search
{
"size": 0,
"aggs": {
"min_age": {
"nested": {
"path": "comments"
},
"aggs": {
"min_age": {
"min": {
"field": "comments.age"
}
}
}
}
}
}
结语
通过本文的介绍,你应该对Elasticsearch中的nested
类型有了更深入的理解。nested
类型提供了一种有效的方式来处理和查询嵌套数据结构,是处理复杂数据关系的强大工具。希望本文能够帮助你在实际项目中更好地应用ES的nested
类型。