我可以在 MongoDB 的聚合查询中申请 forEach 吗? [英] Can I apply forEach in aggregate query in MongoDB?

查看:10
本文介绍了我可以在 MongoDB 的聚合查询中申请 forEach 吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个成员集合,根据特定条件查找成员,在获取成员后,我需要对每个成员进行一些计算.在同一个集合上计算需要查询.

I have a member collection and find members by specific conditions and after get members I need to do some calculation for each member. To calculate need query on the same collection.

我的过程是

var eachMemberInfo = [];
var members = db.collection('member').find({ createdDate: currentDate, country: 'BD'}).toArray();
members.forEach(function(doc) {
  var result = db.collection('member').aggregate([
    { $match: { memberType: doc.memberType, country : doc.country } },
    {
      $group: {
        _id: {memberType:"$memberType",country:"$country"},
        memberCount: { $sum: {$cond:[{$gt: ["$numberOfInvitees",0]},1,0]} },
        lessCount: { $sum: {$cond:[{$and:[{$lt:["$numberOfInvitees", doc.numberOfInvitees]}, {$gt: ["$numberOfInvitees",0]}]},1,0]} },
        sameCount: { $sum: {$cond:[{$eq: ["$numberOfInvitees",doc.numberOfInvitees]},1,0]} }
      }
    }
  ]).toArray();

   eachMemberInfo.push({memberId:doc.memberId,memberCount: result[0].memberCount, lessCount: result[0].lessCount});

});

我的问题是如何使用单个聚合查询来做到这一点?

谁能帮帮我:)

例如:

会员收藏喜欢:

[{
    "_id" : ObjectId("57905b2ca644ec06142a8c06"),
    "memberID" : 80,
    "memberType" : "N",
    "numberOfInvitees" : 2,
    "createdDate" : ISODate("2016-07-21T00:00:00.000Z"),
    "country" : "BD"
},
{
    "_id" : ObjectId("57905b2ca644ec06142a8c09"),
    "memberID" : 81,
    "memberType" : "N",
    "numberOfInvitees" : 3,
    "createdDate" : ISODate("2016-07-21T00:00:00.000Z"),
    "country" : "BD"
}
{
    "_id" : ObjectId("57905b2ca644ec06142a8fgh"),
    "memberID" : 82,
    "memberType" : "N",
    "numberOfInvitees" : 4,
    "createdDate" : ISODate("2016-07-21T00:00:00.000Z"),
    "country" : "BD"
}
{
    "_id" : ObjectId("57905b2ca644ec06142a8cfgd"),
    "memberID" : 83,
    "memberType" : "N",
    "numberOfInvitees" : 1,
    "createdDate" : ISODate("2016-07-21T00:00:00.000Z"),
    "country" : "BD"
}
{
    "_id" : ObjectId("57905b2ca644ec06142a8cfgd"),
    "memberID" : 84,
    "memberType" : "N",
    "numberOfInvitees" : 2,
    "createdDate" : ISODate("2016-07-21T00:00:00.000Z"),
    "country" : "BD"
}
..............
]

eachMemberInfo 中的预期结果如:

[
  { memberID : 80, memberCount:5,lessCount: 1,sameCount:2 },
  { memberID : 81, memberCount:5,lessCount: 3,sameCount:1 },
  { memberID : 82, memberCount:5,lessCount: 4,sameCount:1 },
  { memberID : 83, memberCount:5,lessCount: 0,sameCount:1 },
  { memberID : 84, memberCount:5,lessCount: 1,sameCount:2 }
]

推荐答案

你不能用聚合管道做到这一点.你应该明白 MongoDB 聚合是一系列应用于集合的特殊运算符.当您执行聚合管道时,MongoDB 将运算符相互传递,即运算符的输出成为以下运算符的输入.每个运算符的结果是一个新的文档集合.

You can't do that with the aggregation pipeline. You should understand that MongoDB aggregation is a series of special operators applied to a collection. When you execute an aggregation pipeline, MongoDB pipes operators into each other i.e. the output of an operator becomes the input of the following operator. The result of each operator is a new collection of documents.

因此,您在上面尝试实现的目标可以简单地重写为以下管道,而无需先创建文档数组:

Hence what you are trying to achieve in the above can be simply rewritten as the following pipeline without the need to create an array of documents first:

var collection = db.collection('member'), 
    pipeline = [
        { "$match": { createdDate: currentDate, country: 'BD' } },
        {
            "$group": {
                "_id": { "memberType": "$memberType", "country": "$country" },
                "memberCount": { 
                    "$sum": { "$cond":[ { "$gt": ["$numberOfInvitees", 0] }, 1, 0 ] } 
                },
                "sameCount": { "$sum": 1 } 
            }
        }
    ];

collection.aggregate(pipeline, function(err, result){
    if (err) throw err;
    console.log(result);
});

<小时>

更新

跟进您的问题的更改,运行以下聚合管道将为您提供所需的结果:

Follow-up to the changes to your question, running the following aggregation pipeline will give you the desired result:

var collection = db.collection('member'), 
    pipeline = [   
        { "$match": { createdDate: currentDate, country: 'BD' } },
        {
            "$group": {
                "_id": { 
                    "memberType": "$memberType", 
                    "country": "$country" 
                },            
                "invitees":{ 
                    "$push":  {
                        "memberID": "$memberID",
                        "count": "$numberOfInvitees"
                    }
                },
                "inviteesList": { "$push": "$numberOfInvitees" },
                "memberCount": { "$sum": 1 } 
            }
        },
        { "$unwind": "$invitees" },
        { "$unwind": "$inviteesList" },
        { 
            "$group": {
                "_id": "$invitees.memberID",
                "sameInviteesCount": { 
                     "$sum": { 
                        "$cond": [ 
                            { "$eq": ["$inviteesList", "$invitees.count"] }, 
                            1, 0 
                        ] 
                    }
                },
                "lessInviteesCount": { 
                    "$sum": { 
                        "$cond":[ 
                            { "$lt": ["$inviteesList", "$invitees.count"] }, 
                            1, 0 
                        ] 
                    }
                },
                "memberCount": { "$first": "$memberCount" }
            }
        }
    ];

collection.aggregate(pipeline, function(err, result){
    if (err) throw err;
    console.log(result);
});

这篇关于我可以在 MongoDB 的聚合查询中申请 forEach 吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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