nodejs + mongoose - 查询聚合 [英] nodejs + mongoose - query aggregate

查看:52
本文介绍了nodejs + mongoose - 查询聚合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 node.js 应用上有这个架构.我正在使用猫鼬:

var todoSchema = new Schema({任务:字符串,描述:字符串,日期:日期,状态:字符串,清单:布尔值,用户:字符串});

我想得到这个结果,所以我可以把它传递给谷歌图表并在图表上显示:

<预><代码>[{"用户": "A",细节" :[打开":3,进步":5,完成":7存档":10]},{"用户": "B",细节" :[打开":4,进步":9,完成":14存档":12]}]

但我的查询看起来不对:

Todo.find().distinct( "user", function(err, users){Todo.find({"user": {"$in": users}}, function(err, todo){如果(错误)res.send(err);var finalResult = [];finalResult.push(todo);res.send(finalResult);//res.send(todo);});});});

有人可以帮我吗?非常感谢您的帮助.

解决方案

使用聚合框架 并运行以下聚合管道,该管道使用两个 $group 和 $project 管道步骤;第一个是按 user 字段对文档进行分组并使用 $cond 运算符/reference/operator/aggregation/sum/#grp._S_sum" rel="nofollow">$sum 累加器运算符表达式,用于根据状态字段评估计数.第二个$group 管道步骤将使用累加器运算符 $push 返回每个组的表达式值数组.最后一步$project 将通过将 _id 字段重命名为 user 来修改文档字段:

var 管道 = [{$组":{"_id": "$user",open_count":{$sum":{"$cond": [ { "$eq": [ "$status", "open" ] }, 1, 0 ]}},进度计数":{$sum":{"$cond": [ { "$eq": [ "$status", "progress" ] }, 1, 0 ]}},完成计数":{$sum":{"$cond": [ { "$eq": [ "$status", "done" ] }, 1, 0 ]}},归档计数":{$sum":{"$cond": [ { "$eq": [ "$status", "archive" ] }, 1, 0 ]}}}},{$组":{"_id": "$_id",细节": {$推":{"open": "$open_count","progress": "$progress_count","done": "$done_count","archive": "$archive_count"}}}},{$项目":{_id":0,用户":$_id",详细信息":1}}];Todo.aggregate(pipeline, function (err, result){如果(错误)res.send(错误);console.log(JSON.stringify(result, undefined, 4));res.send(结果);})

I have this schema on my node.js app. I'm using mongoose:

var todoSchema = new Schema({
  task: String,
  description: String,
  date: Date,
  status: String,
  checklist: Boolean,
  user: String
});

I want to get this result, so I can pass it into google chart and display it on chart:

[
  {
    "user": "A",
    "detail" :
    [
      "open" : 3,
      "progress" : 5,
      "done" : 7
      "archive" : 10
    ]
  },
  {
    "user": "B",
    "detail" :
    [
      "open" : 4,
      "progress" : 9,
      "done" : 14
      "archive" : 12
    ]
  }
]

But my query looks wrong:

Todo.find().distinct( "user", function(err, users){
    Todo.find({"user": {"$in": users}}, function(err, todo){
      if (err)
        res.send(err);

      var finalResult = [];
      finalResult.push(todo);
      res.send(finalResult);
      //res.send(todo);
    });
  });
});

Anybody can help me, please? Really appreciated your help.

解决方案

Use aggregation framework and run the following aggregation pipeline which uses two $group and $project pipeline steps; the first one is to group your documents by the user field and use the $cond operator in the $sum accumulator operator expression to evaluate the counts based on the status field. The second $group pipeline step will add the detail array by using the accumulator operator $push that returns an array of expression values for each group. The last step $project will modify the document fields by renaming the _id field to user:

var pipeline = [
    { 
        "$group": { 
            "_id": "$user",             
            "open_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "open" ] }, 1, 0 ]
                }
            },
            "progress_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "progress" ] }, 1, 0 ]
                }
            },
            "done_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "done" ] }, 1, 0 ]
                }
            },
            "archive_count": {
                "$sum": {
                    "$cond": [ { "$eq": [ "$status", "archive" ] }, 1, 0 ]
                }
            } 
        }  
    },
    {
        "$group": {
            "_id": "$_id",            
            "detail": {
                "$push": {
                    "open": "$open_count",
                    "progress": "$progress_count",
                    "done": "$done_count",
                    "archive": "$archive_count"
                }
            }
        }
    },
    {
        "$project": {
            "_id": 0, "user": "$_id", "detail": 1
        }
    }
];


Todo.aggregate(pipeline, function (err, result){
    if (err) res.send(err);
    console.log(JSON.stringify(result, undefined, 4));
    res.send(result);
})

这篇关于nodejs + mongoose - 查询聚合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆