想知道哪种查询可以在不执行太多聚合阶段的情况下以最佳方式产生以下结果。
示例文档
{
"_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'数组中获得那些名称等于"cheese"的嵌入对象。
注意:
- 不要考虑在'foods'数组中嵌入对象,如果它的名称不等于"cheese">
- 不要考虑在'customers'数组中嵌入对象,如果它有一个空的'foods'数组字段。
预期输出
{
"_id" : ObjectId("62d6699126d40c3cbca985f7"),
"name" : "Cafe2",
"customers" : [
{
"name" : "David",
"foods" : [
{
"name" : "cheese"
}
]
},
{
"name" : "Ram",
"foods" : [
{
"name" : "cheese"
}
]
}
]
}
查询
- 客户地图
- 并将食品数组替换为过滤后的数组
- 过滤数组只包含含有
name = cheese or empty array
的食品 - 对顾客进行过滤,去除那些空食物
*你可以在一个阶段把它们结合起来,但我认为你不能用更短的时间来完成。$reduce + filter
可以代替map+filter+filter
,但还原和concat arrays
速度较慢。
Playmongo
aggregate(
[{"$set":
{"customers":
{"$map":
{"input": "$customers",
"in":
{"$mergeObjects":
["$$this",
{"foods":
{"$filter":
{"input": "$$this.foods",
"cond": {"$eq": ["$$this.name", "cheese"]}}}}]}}}}},
{"$set":
{"customers":
{"$filter":
{"input": "$customers", "cond": {"$ne": ["$$this.foods", []]}}}}}])