展开只是如果嵌入式存在

unwind just if embedded exist

我有高度嵌套的 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
              }
          ]
       }
    ]
}  

我对这个子文档使用了一些操作,比如排序和求和,所以我使用了

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
       }
    ]
}  

但是如果产品文档不存在,我得到的结果是空的。即使产品文档不存在,我也想获得包含公司信息的结果。

首先,您可以使用"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
        }
    ]
}