简体   繁体   English

在 mongodb 中查找聚合数据

[英]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"
    }
  ]
})

You can check it out here你可以在这里查看

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.如果您“自上而下”而不是自上而下地看待它,则会有所帮助。

  • We want to find carts with both P1 and P2, so we want to filter我们想找到同时有 P1 和 P2 的购物车,所以我们要过滤
    on that.在那。 To make it a little more generic, we will set up a为了使其更通用一点,我们将设置一个
    target array variable "targs" with ["P1","P2"]使用 ["P1","P2"] 的目标数组变量 "targs"
  • We will use $map as a way to take the CUSTOMER.SHOPPINGCART array我们将使用$map作为获取CUSTOMER.SHOPPINGCART数组的一种方式
    and pass it to $filter并将其传递给$filter
  • The array after $filter will contain 0 to n items; $filter之后的数组将包含 0 到 n 个项目; we get the我们得到
    length with the $size operator and capture that in npids .使用$size运算符长度并在npids中捕获它。
  • We now have an array of {cartId,npids} objects...我们现在有一个{cartId,npids}对象数组...
  • ...which we use as input to the "outer" $filter to only keep those ...我们将其用作“外部” $filter的输入以仅保留那些
    objects where npids == targs.length which means ALL the products npids == targs.length 表示所有产品的对象
    appeared in that cart.出现在那个购物车里。
  • The whole thing is projected as XX .整个事情被投影为XX
  • Many docs will not have any matches and XX will be size 0. We许多文档没有任何匹配项, XX的大小为 0。我们
    can use $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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM