如何分组mongodb和mongoose的调查结果?

时间:2015-10-08 10:25:58

标签: mongodb mongoose mongodb-query aggregation-framework

我的应用中有一个动作集合,它具有以下对象结构:

var sourcePart = @"public class Example 
{
    public string Name { get; set; }
    public string Surname { get; set; }
    public string Cellphone { get; set; }
    public string Address { get; set; }
    public string CompanyName { get; set; }
    public DateTime CurrentDate { get; set; }
}";

    var sourceTemplate = @"using System;

    @code

";

var code = sourceTemplate.Replace("@code", sourcePart);

CSharpCodeProvider c = new CSharpCodeProvider();

CompilerParameters cp = new CompilerParameters();

CompilerResults cr = c.CompileAssemblyFromSource(cp, code);
if (cr.Errors.Count > 0)
{
    MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
        "Error evaluating cs code", MessageBoxButtons.OK,
           MessageBoxIcon.Error);
    return;
}

var a = cr.CompiledAssembly;

var type = a.GetTypes().Single();

string[] propertyNames = type.GetProperties().Select(p => p.Name).ToArray();

我需要在mongodb和mongoose中返回一个返回以下内容的结果:

    {
        "type" : "evMove",
        "userId" : "55fbbb2a34d594085988aa70",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023f"
        }
    },
    {
        "type" : "game",
        "userId" : "55fgdfa34d594085988aa70",
        "data" : {
            ...
        }
    },
    {
        "type" : "evMove",
        "userId" : "55fbbb2aasd34d595988aa60",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023f"
        }
    },
{
        "type" : "evMove",
        "userId" : "55fbbb2a34d594085988aa30",
        "data" : {
            "evId"   : "55fdaa53cca301f758f4023d",
            "moveId" : "55fdaa53cca301f758f4023g"
        }
    }

如果我在javascript中执行此操作并且没有类似查询的组,则表示以下内容:

 for event id: 55fdaa53cca301f758f4023d

  moveId:55fdaa53cca301f758f4023d, count:2
  moveId:55fdaa53cca301f758f4023g, count:1

我怎样才能通过这种方式为我提供mongodb和mongoose中我想要的结果(移动和计数)?

1 个答案:

答案 0 :(得分:2)

您希望.aggregate()能够在指定的键上“分组”。首先,您将两者分组,虽然不完全按照您要求的格式,但第二个$group将结果汇总到一个数组中:

Model.aggregate([
    { "$match": {
        "type": "evMove",
        "data.evId": new ObjectId("55fdaa53cca301f758f4023d")
    }},
    { "$group": {
        "_id": {
            "evId": "$data.evId",
            "moveId": "$data.moveId"
        },
        "count": { "$sum": 1 }
    }},
    { "$group": {
        "_id": "$_id.evId",
        "moves": {
            "$push": { 
                "moveId": "$_id.moveId",
                "count": "$count"
            }
        }
    }}
],function(err,results) {
    // results in here
});

这给你一个像这样的结果:

{ 
    "_id": "55fdaa53cca301f758f4023d",
    "moves": [
        { "moveId": "55fdaa53cca301f758f4023d", "count": 2 }
        { "moveId": "55fdaa53cca301f758f4023g", "count": 1 }
    ]

}

另请注意,如果您希望将其用于“多个”eventId值,则只需从$match中删除该行。

当然,由于聚合管道不执行mongoose在其他.find()类型操作(基于模式)中执行的“自动调用”,因此您需要自己“转换”类型。因此来自核心驱动程序的ObjectId方法。但只有当您需要$match内容为_id值时才需要这样做,因为所有其他评估都是管道本身的内部。