在 Elasticsearch 中,flattened
类型是一种特别设计的字段类型,用于存储具有不规则结构的 JSON 数据。与 nested
类型不同,flattened
类型将嵌套的 JSON 对象展平(即将嵌套对象的字段变成一级字段,字段名以“点”分隔)。这种类型适用于存储字段数量和结构变化较大的数据,并且支持高效的查询。
使用Flattened类型可以将整个JSON对象及其Nested字段索引为单个关键字(keyword类型)字段,以此减少字段总数。
1. 创建索引并定义 Flattened 类型
与嵌套类型不同,flattened
类型是用于存储具有复杂、变化字段的结构。它将复杂对象展平,允许更灵活的查询和存储。
示例:创建索引并定义 flattened
类型字段
PUT /products
{"mappings": {"properties": {"name": {"type": "text"},"price": {"type": "float"},"attributes": {"type": "flattened" // 使用 flattened 类型}}}
}
在此示例中,attributes
字段是一个 flattened
类型,可以存储任意复杂的 JSON 对象。
2. 增加文档(Indexing)
在增加文档时,你可以直接传入一个包含嵌套结构的 JSON 数据,Elasticsearch 会自动将其“展平”。
示例:向 products
索引添加文档
POST /products/_doc/1
{"name": "Laptop","price": 1200.99,"attributes": {"color": "black","screen_size": "15 inches","brand": "BrandX","specs.cpu": "Intel i7","specs.ram": "16GB"}
}
在这个示例中,attributes
字段包含了一些简单的键值对和一个嵌套的对象(specs
),这些内容都会被展平为一个扁平的结构。
3. 查询文档(Search)
flattened
类型字段的查询方式与普通字段类似,使用 match
、term
或其他查询类型。
查询包含特定属性的文档
假设我们想查找所有具有 specs.cpu
属性且值为 “Intel i7” 的文档:
POST /products/_search
{"query": {"match": {"attributes.specs.cpu": "Intel i7"}}
}
查询特定属性(如 color
)的文档
POST /products/_search
{"query": {"term": {"attributes.color": "black"}}
}
使用聚合进行查询
你还可以在 flattened
类型字段上执行聚合操作,进行统计或分组。
POST /products/_search
{"aggs": {"attribute_colors": {"terms": {"field": "attributes.color"}}}
}
4. 更新文档(Update)
更新 flattened
类型的字段与普通字段的更新方式相似。在更新时,你可以通过脚本来修改或添加新的展平字段。
示例:更新 attributes
字段
假设我们想要更新文档中的 color
属性,将其改为 “silver”:
POST /products/_update/1
{"doc": {"attributes":{"color": "silver"}}
}
如果想要在 attributes
中添加一个新的键值对(例如 specs.gpu
):
POST /products/_update/1
{"doc": {"attributes":{"specs.gpu": "NVIDIA GTX 1650"}}
}
5. 删除文档(Delete)
删除文档的操作与普通的删除操作相同。flattened
类型字段并不影响删除操作。
DELETE /products/_doc/1
6. 删除字段(Partial Delete)
如果你只想从 flattened
字段中删除某个字段,可以使用脚本来实现。
示例:删除 attributes.specs.cpu
字段
POST /products/_update/1
{"script": {"source": "ctx._source.attributes.remove('specs.cpu')"}
}
总结
在 Elasticsearch 中,flattened
类型字段非常适合存储结构化和非结构化的数据,它将嵌套的数据展平成平面结构,并可以通过简单的键值对来访问。在增、删、改、查操作上,flattened
类型非常灵活:
- 增(Indexing):直接将复杂的 JSON 对象存入字段,Elasticsearch 会自动展平。
- 查(Search):通过常规查询语法查询展平后的字段。
- 改(Update):可以通过
doc
语法更新或添加新的字段。 - 删(Delete):可以删除整个文档或通过脚本删除字段。