如果嵌入存在就放松

时间:2016-10-03 19:13:41

标签: php mongodb mongodb-query aggregation-framework mongodb-aggregation

我有高度嵌套的mongodb对象集,所以我的集合是:

{
   "_id":17846384es,
   "company_name":"company1",
   "company_location":"city1",
    "phone":"xxxxx",
   "open_time":"xxx",
   "products":[
       {
         "product_id":"123785",
         "product_name":"product1",
         "user_votes":[
              {
                 "user_id":1,
                  "vote":1
              },
              {
                 "user_id":2,
                  "vote":2
              }
          ]
       },
       {
         "product_id":"98765",
         "product_name":"product2",
         "user_votes":[
              {
                 "user_id":5,
                  "vote":3
              },
              {
                 "user_id":3,
                  "vote":3
              }
          ]
       }
    ]
}  

我在这个文档子上使用了sort和sum之类的操作,所以我使用了

db.products.aggregate([
    { $unwind: "$products" },
    { $project: {
        company_name: 1,
        products: {
            product_id: 1,
            product_name: 1,
            user_votes: 1,
            votes: { $sum: "$products.user_votes.vote" }
        } 
    } },
    { $sort: { totalVotes: -1 } },
    {
        $group: {
            _id: "$_id",
            company_name: { $first: "$company_name" },
            products: { $push: "$products" }
        }
    }
])  

得到这个结果:

{
   "_id":17846384es,
   "company_name":"company1",
   "products":[
       {
         "product_id":"98765",
         "product_name":"product2",
         "user_votes":[
              {
                 "user_id":5,
                  "vote":3
              },
              {
                 "user_id":3,
                  "vote":3
              }
          ]
        "votes":6
       },
       {
         "product_id":"123785",
         "product_name":"product1",
         "user_votes":[
              {
                 "user_id":1,
                  "vote":1
              },
              {
                 "user_id":2,
                  "vote":2
              }
          ],
          "votes":3
       }
    ]
}  

但如果产品文档存在,我的结果为空。即使产品文档不存在,我也希望得到公司信息的结果。

1 个答案:

答案 0 :(得分:1)

首先,您可以使用"preserveNullAndEmptyArrays"来保留没有产品数组的公司。

以下查询应输出公司名称,即使它没有产品数组。

我认为您正在尝试总结投票并对产品数组进行排序,以获得最多数量的产品作为数组中的第一个元素。以下查询应该产生结果。

db.product.aggregate([
    { $unwind: { path : "$products", preserveNullAndEmptyArrays : true }},
    { $project: {
        company_name: 1,
        products : { $ifNull : ["$products", "0"]}}            
    },
    { $project: {
        company_name: 1,
        products: {
            product_id: 1,
            product_name: 1,
            user_votes: 1,
            votes: { $sum: "$products.user_votes.vote" }
        } 
    } },
    { $sort: { "products.votes": -1 } },
    {
        $group: {
            _id: "$_id",
            company_name: { $first: "$company_name" },
            products: { $push: "$products" }
        }
    },  

]);  

如果您想保留最终没有产品的公司。您可以将此附加排序添加为上述查询中的最后一个管道。

{ $sort: { "products.votes": -1 } },

没有产品阵列的公司的输出如下: -

{
    "_id" : ObjectId("57f2bd50dd4752c20947fd03"),
    "company_name" : "company2",
    "products" : [ 
        {
            "votes" : 0
        }
    ]
}