我想过滤MONGO db中的多个嵌套文档
示例JSON:
--allow-empty
}
预期输出:仅过滤具有available_qty <50和> 10的成员(不是全部)和members.product_warehouses.available_qty <50和> 20
查询:
{
"_id" : ObjectId("5b5c3afbcc43cb5ed64b7a04"),
"id" : NumberLong(15015060),
"name" : "1801_Conf",
"type" : NumberInt(2),
"members" : [
{
"id" : NumberLong(15015061),
"name" : "1801_Conf-W--",
"sku" : "1801_new",
"type" : NumberInt(1),
"parent_id" : NumberLong(15015060),
"available_qty" : NumberInt(10),
"on_hand_qty" : NumberInt(10),
"outgoing_qty" : NumberInt(0),
"incoming_qty" : NumberInt(0),
"shortage_qty" : NumberInt(0),
"product_warehouses" : [
{
"warehouse_id" : NumberLong(3),
"available_qty" : NumberInt(10),
"outgoing_qty" : NumberInt(0),
"incoming_qty" : NumberInt(0)
},
{
"warehouse_id" : NumberLong(4),
"available_qty" : NumberInt(600),
"outgoing_qty" : NumberInt(0),
"incoming_qty" : NumberInt(0)
}
],
]
}
]
错误::{“ ok”:0,“ errmsg”:“无效的运算符'$ elemMatch'”,“ code”:15999}:聚合失败
答案 0 :(得分:1)
您需要首先$filter
个members
数组,同时必须将$filter
应用于product_warehouses
数组,并循环遍历已过滤的{{1} }使用$map
聚合的数组。
最后,您需要将members
与$and
,$gt
和$eq
聚合运算符放在一起,这与您的预期输出条件相同
cond
给它一个try
答案 1 :(得分:1)
请尝试以下查询,它可以完美且经过正确测试
db.test.aggregate(
// Pipeline
[
// Stage 1
{
$unwind: {
path : "$members",
includeArrayIndex : "arrayIndex", // optional
preserveNullAndEmptyArrays : false // optional
}
},
// Stage 2
{
$match: {
$and: [
{"members.available_qty": {$gte:10}},
{"members.available_qty": {$lte:50}}
]
}
},
// Stage 3
{
$project: {
"_id" :1,
"id" :1,
"name" :1,
"type" :1,
"members" : {
"id":1,
"name" :1,
"sku" : 1,
"type" :1,
"parent_id" :1,
"available_qty" :1,
"on_hand_qty" :1,
"outgoing_qty" :1,
"incoming_qty" :1,
"shortage_qty" :1,
"product_warehouses": {
$filter: {
input: "$members.product_warehouses",
as: "item",
cond: {
"$and": [
{ "$gte": [ "$$item.available_qty", 20] },
{ "$lte": [ "$$item.available_qty", 50 ] },
]
}
}
}
},
}
},
// Stage 4
{
$match: {
"members.product_warehouses":{$ne: []}
}
},
// Stage 5
{
$group: {
_id:"$_id",
"id" :{ $last: '$id' },
"name" :{ $last: '$name' },
"type" : { $last: '$type' },
members: { $addToSet: "$members" }
}
},
],
);
答案 2 :(得分:1)
据我了解,这是您需要的查询。
db.col.aggregate([
{"$unwind" : "$members"},
{"$match" : {"$and" : [{"members.available_qty" : {"$lt" : 50}},{"members.available_qty" : {"$gt" : 10}}]}},
{"$match" : {"$and" : [{"members.product_warehouses.available_qty" : {"$lt" : 50}},{"members.product_warehouses.available_qty" : {"$gt" : 20}}]}},
{"$group" : {"_id" : "$_id",
"type" : {"$first" : "$type"},
"name" : {"$first" : "$name"},
"id" : {"$first" : "$id"},
"members" : {"$addToSet" : "$members"}
}
}
]);
或
db.lo.aggregate([
{"$unwind" : "$members"},
{"$match" : {
"$and" : [
{"members.available_qty" : {"$lt" : 50}},
{"members.available_qty" : {"$gt" : 10}}
]
}
},
{"$match" : {
"members.product_warehouses": {
"$elemMatch":{
"available_qty": { "$lt": 50 },
"available_qty": { "$gt": 20 }
}
}
}},
{"$group" : {"_id" : "$_id",
"type" : {"$first" : "$type"},
"name" : {"$first" : "$name"},
"id" : {"$first" : "$id"},
"members" : {"$addToSet" : "$members"}
}
}
]);
如果任何一个子文档都符合以下条件 members.product_warehouses.available_qty> 20和members.product_warehouses.available_qty <50 ,它将返回整个product_warehouses数组,与 $ elemMatch
答案 3 :(得分:1)
您可以使用以下聚合查询。由于$elemMatch
在$project
阶段不是有效的运算符,因此您可以用here,$filter
和$size
比较来代替该部分。
{"members":{
"$filter":{
"input":"$members",
"cond":{
"$and":[
{"$gte":["$$this.available_qty",10]},
{"$lte":["$$this.available_qty",50]},
{"$gt":[
{"$size":{
"$filter":{
"input":"$$this.product_warehouses",
"cond":{
"$and":[
{"$gte":["$$this.available_qty",20]},
{"$lte":["$$this.available_qty",50]}
]
}
}
}},
0
]}
]
}
}
}}