【问题标题】:An aggregation puzzle about mongoDB?关于 mongoDB 的聚合难题?
【发布时间】:2017-06-27 03:54:25
【问题描述】:

我这样定义数据模型:

import mongoose from 'mongoose';

const schema = mongoose.Schema({
    title: {type: String, required: true},
    content: {type: String, required: true},
    language: {type: String, required: true},
    label: [{type: String, required: false}],
    createTime: {type: Date, default: Date.now},
    updateTime: {type: Date, default: Date.now}
});

const Snippet = mongoose.model('Snippet', schema, 'snippet');

export default Snippet;

我想要的是当我使用时:

Snippet.aggregate({...})

如果数据是:

[{
    title: 'a',
    content: 'b',
    language: 'javascript'
},{
    title: 'a',
    content: 'b',
    language: 'javascript',
    label: ['new', 'old']
},
{
    title: 'a',
    content: 'b',
    language: 'javascript',
    label: ['old']
}]

那么我想要的结果应该是这样的:

{
   languageCount : [
   {
    language : 'javascript',
    count : 3
   }],
   labelCount : [
   {
    label : 'new',
    count : 1
   },
   {
    label : 'old',
    count : 2
   }]
}

我不知道如何完成我的“...”部分。

任何对此有任何想法或任何其他方式的人都可以解决它请告诉我,非常感谢!

【问题讨论】:

  • 你的mongod是什么版本?
  • 我的 mongod 版本是 3.2.1。如果你可以使用基于最新版本的某些功能,我可以接受。

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

如果您的 mongod 版本

[
   {
      "$unwind":"$label"
   },
   {
      "$group":{
         "_id":{
            "lang":"$language",
            "label":"$label"
         },
         "count_label_per_lang":{
            "$sum":1
         }
      }
   },
   {
      "$group":{
         "_id":"$_id.lang",
         "labels":{
            "$push":{
               "label":"$_id.label",
               "count":"$count_label_per_lang"
            }
         },
         "count":{
            "$sum":"$count_label_per_lang"
         }
      }
   }
]

【讨论】:

    【解决方案2】:

    使用聚合时可以做的是包含 language:label 的组合索引。

    假设您要返回一个承诺,我会执行以下操作:

        const projection = {  _id: 1, labels : 1, count:1, languageCount:1 }
        const responsePromise = Snippet.aggregate([
          {
            $unwind:"$label"
          },
          {
            $group:{
               _id: {language: "$language", label : "$label"},
               languageCount:{$sum:1}
            }
          },
          {
            $group:{
               _id:"$_id.language",
               labels:{
                  $push:{
                    label:"$_id.label",
                    count:"$languageCount"
                  }
               },
             count:{$sum:"$languageCount"}
            }
         },
         { $project : projection }]);
    
        return responsePromise;
    

    在调用者代码上,您必须执行以下操作:

    responsePromise.then((data,error) => {
      response.json({content:data})
    });
    

    我相信会这样。

    【讨论】:

    • 不工作... [ { _id: null, 标签: [ [Object], [Object] ], count: 0 } ]
    • 第二个 id 中缺少双引号。我的答案已被编辑。请立即检查。我刚刚在这里进行了测试,它确实有效。
    • [{"_id":null,"labels":[{"label":"old"},{"label":"new"}],"count":0}]顺便说一句,双引号不是你错过的唯一部分......
    • 我只是从我的代码中复制/粘贴,它确实有效。请再次检查。我建议你对试图帮助你的人更加友好和礼貌。
    • 如果我的话冒犯了你,我对此表示歉意......感谢你的帮助,我刚刚再次检查,结果是 [{"_id":null,"count":2} ],你认为这可能是由mongoDB版本问题引起的吗,我的是3.2.1,我的猫鼬版本是4.7.4。
    【解决方案3】:

    感谢@Styvane 的启发,我的最终答案基于 mongoDB 3.4。

    db.getCollection('snippet').aggregate([
        {
            "$facet": {
                "languageCount": [
                    {
                        "$sortByCount": "$language"
                    },
                    {
                        "$addFields": {
                            "language": "$_id"
                        }
                    },
                    {
                        "$project": {
                            "_id": 0
                        }
                    }
                ],
                "labelCount": [
                    {
                        "$unwind": "$label"
                    },
                    {
                        "$sortByCount": "$label"
                    },
                    {
                        "$addFields": {
                            "label": "$_id"
                        }
                    },
                    {
                        "$project": {
                            "_id": 0
                        }
                    }
                ]
            }
        }
    ])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2015-10-08
      • 2014-03-05
      • 2023-02-23
      • 2017-09-03
      • 2021-12-14
      相关资源
      最近更新 更多