求最优MongoDB查询:筛选foods中name为cheese的嵌套对象
MongoDB 嵌套数组筛选优化查询
需要编写最优MongoDB查询语句,在尽可能减少聚合阶段的前提下,实现以下目标:
- 从文档的
customers数组中,仅保留其foods数组里name等于"cheese"的嵌套对象 - 移除
foods数组中所有name不等于"cheese"的对象 - 移除处理后
foods数组为空的customers条目
示例文档
{ "_id" : ObjectId("62d6699126d40c3cbca985f7"), "name" : "Cafe2", "customers" : [ { "name" : "David", "foods" : [ { "name" : "cheese" }, { "name" : "beef" } ] }, { "name" : "Bill", "foods" : [ { "name" : "fish" } ] }, { "name" : "Ram", "foods" : [ { "name" : "cheese" }, { "name" : "beef" }, { "name" : "paneer" } ] } ] }
注意事项
- 若
foods数组中的嵌套对象name不等于"cheese",直接丢弃该对象 - 若
customers数组中的对象处理后foods数组为空,直接丢弃该customers对象
最优查询语句
仅用1-2个聚合阶段即可完成需求,兼顾性能和简洁性:
db.collection.aggregate([ { $project: { name: 1, customers: { $filter: { input: { $map: { input: "$customers", as: "cust", in: { name: "$$cust.name", foods: { $filter: { input: "$$cust.foods", as: "food", cond: { $eq: ["$$food.name", "cheese"] } } } } } }, as: "filteredCust", cond: { $ne: ["$$filteredCust.foods", []] } } } } }, // 可选:如果需要过滤掉处理后customers数组为空的文档,添加此阶段 { $match: { customers: { $ne: [] } } } ])
语句说明
- 内层
$map+$filter:遍历每个customers对象,对其foods数组做过滤,仅保留name为"cheese"的条目 - 外层
$filter:遍历处理后的customers数组,移除那些foods数组为空的对象 - 可选
$match阶段:如果存在处理后customers数组为空的文档,可通过此阶段过滤掉这类文档
预期输出
{ "_id" : ObjectId("62d6699126d40c3cbca985f7"), "name" : "Cafe2", "customers" : [ { "name" : "David", "foods" : [ { "name" : "cheese" } ] }, { "name" : "Ram", "foods" : [ { "name" : "cheese" } ] } ] }
内容的提问来源于stack exchange,提问作者Gautam Bajaj
相关产品推荐
相关产品推荐

