[英]find data with aggregation in mongodb
db.customer.insert([
{"_id": "C1",
"CUSTOMER" : { "customerId" : "C1",
"customerName" : "Tony",
"SHOPPINGCART":[{ "cartId" : "cart001",
"purchased": "no",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P2",
"quantity" : 2 },
{ "prodListId" : 2,
"productId" : "P1",
"quantity": 1 } ]
},
{ "cartId" : "cart002",
"purchased": "yes",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P2",
"quantity": 3 } ]
},
{ "cartId" : "cart006",
"purchased": "yes",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P3",
"quantity": 3 } ]
} ]
}
},
{"_id":"C2",
"CUSTOMER" : { "customerId" : "C2",
"customerName" : "James",
"SHOPPINGCART":[
{ "cartId" : "cart003",
"purchased": "yes",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P2",
"quantity" : 2 },
{ "prodListId" : 2,
"productId" : "P3",
"quantity": 1 } ]
},
{ "cartId" : "cart004",
"purchased": "no",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P1",
"quantity": 3 } ]
},
{ "cartId" : "cart005",
"purchased": "no",
"containsProdList" : [
{ "prodListId" : 1,
"productId" : "P2",
"quantity": 1 } ]
}]
}
}
]);
Above code is my data in JSON form, and I want to extract the customer who purchased both of "P1" and "P2".上面的代码是我在 JSON 表格中的数据,我想提取同时购买“P1”和“P2”的客户。
db.shoppingCart.aggregate([{
$unwind: {
path: '$CUSTOMER.creates.SHOPPINGCART'
}
}, {
$match: {
'CUSTOMER.creates.SHOPPINGCART.dateClosed': {
$ne: null
},
$and: [
{
'CUSTOMER.creates.SHOPPINGCART.containsProdList.productId': 'P1002'
},
{
'CUSTOMER.creates.SHOPPINGCART.containsProdList.productId': 'P1003'
}
]
}
}])
I wrote the code like this, but this work when P2 and P3 are in the same shopping cart(output is only C2) while I want to find the customer who purchased regardless of date and shopping cart.我写了这样的代码,但是当 P2 和 P3 在同一个购物车中时(输出只有 C2),当我想找到购买的客户时,不管日期和购物车如何。
Excepted output is both of C1 and C2 since products are in C1's cart002 and cart006, respectively, and their purchased values are set as yes.例外的 output 是 C1 和 C2,因为产品分别在 C1 的购物车 002 和购物车 006 中,并且他们的购买值设置为是。 C2 has both products in the same shopping cart and product list. C2 有两个产品在同一个购物车和产品列表中。
I need your help, guys!我需要你们的帮助,伙计们!
If I got you well, you wanna extract all customers that have purchased productId "P1" and "P2";如果我理解你,你想提取所有购买了 productId "P1" 和 "P2" 的客户; if this is the case, you can make your query like this:如果是这种情况,您可以像这样进行查询:
db.collection.find({
$and: [
{
"CUSTOMER.SHOPPINGCART.containsProdList.productId": "P1"
},
{
"CUSTOMER.SHOPPINGCART.containsProdList.productId": "P2"
}
]
})
Suppose we want to find customers who purchased P1 and P2 (or any arbitrary number) of products but in the same cart.假设我们想要找到购买了 P1 和 P2(或任意数量)产品但在同一个购物车中的客户。 Here is a solution that features no $unwind
and is thus performant even with large arrays of SHOPPINGCART
.这是一个没有$unwind
的解决方案,因此即使使用SHOPPINGCART
的大 arrays 也能表现出色。
It is not initially easy to grok what is happening here, but if it最初了解这里发生的事情并不容易,但如果它
helps if you look at it "depth-up" instead of top-down.如果您“自上而下”而不是自上而下地看待它,则会有所帮助。
$map
as a way to take the CUSTOMER.SHOPPINGCART
array我们将使用$map
作为获取CUSTOMER.SHOPPINGCART
数组的一种方式$filter
并将其传递给$filter
$filter
will contain 0 to n items; $filter
之后的数组将包含 0 到 n 个项目; we get the我们得到$size
operator and capture that in npids
.使用$size
运算符长度并在npids
中捕获它。{cartId,npids}
objects...我们现在有一个{cartId,npids}
对象数组...$filter
to only keep those ...我们将其用作“外部” $filter
的输入以仅保留那些XX
.整个事情被投影为XX
。XX
will be size 0. We许多文档没有任何匹配项, XX
的大小为 0。我们$match
to eliminate those.可以使用$match
来消除这些。var targs = ["P1","P2"];
db.shoppingCart.aggregate([
{$project: {
XX: {$filter: {input: // the "outer" filter
{$map: {input: "$CUSTOMER.SHOPPINGCART", as:"z", in: {
cart: "$$z.cartId",
npids: {$size: {$filter: {input: "$$z.containsProdList", // inner filter
as: "z2",
cond: {$in:["$$z2.productId",targs]} // the heart of the matter
}}
}
} }},
as: "z3",
cond: {$eq:["$$z3.npids",targs.length]}
}}
}}
,{$match: {$expr: {$gt:[{$size: "$XX"},0]} }}
]);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.