嵌套对象与父子文档
本章定位:ES 是扁平存储的,没有 SQL 的 JOIN。但现实数据有关联——课程和评论、订单和商品。nested 和 join 是两种解决方案。
定义与作用
nested 类型:将子对象存储为独立的 Lucene 文档(但关联到父文档),解决 object 类型扁平化导致查询不准的问题。join 类型:在同一索引中定义父子关系,允许 has_child 和 has_parent 查询。
完整示例:课程与评论(nested)
PUT /courses
{
"mappings": {
"properties": {
"title": { "type": "text" },
"reviews": {
"type": "nested",
"properties": {
"user": { "type": "keyword" },
"rating": { "type": "integer" },
"comment": { "type": "text" }
}
}
}
}
}
POST /courses/_search
{
"query": {
"nested": {
"path": "reviews",
"query": {
"bool": {
"must": [
{ "match": { "reviews.comment": "讲得好" } },
{ "range": { "reviews.rating": { "gte": 4 } } }
]
}
}
}
}
}
小结
nested 适合评论、订单行项目等"一对多且需要独立查询"场景。join 适合父子关系但性能开销大。优先考虑扁平化或宽表设计。