这是一个关于在数组中添加一系列数据的最佳方法的问题,我必须匹配另一个元素.我正在try 使用2.2聚合框架,我可以通过一个简单的组来实现这一点.

所以对于给定的一组文档,我试图得到这样的输出;

{
    "result" : [
            {
                "_id" : null,
                "numberOf": 2,
                "Sales" : 468000,
                "profit" : 246246,
            }
    ],
    "ok" : 1
}

现在,我最初有一个文档列表,包含指定给命名属性的值,例如;

[
{
    _id : 1,
    finance: {
        sales: 234000,
        profit: 123123,
    }
}
,
{
    _id : 2,
    finance: {
        sales: 234000,
        profit: 123123,
    }
}
]

这很容易加起来,但由于其他原因,这个 struct 不起作用.例如,可能还有其他类似"finance"的专栏,我希望能够在不创建数千个索引的情况下对它们进行索引,所以我需要转换成这样的 struct ;

[
{
    _id : 1,
    finance: [
        {
            "k": "sales",
            "v": {
                "description":"sales over the year",
                v: 234000,
            }
        },
        {
            "k": "profit",
            "v": {
                "description":"money made from sales",
                v: 123123,
            }
        }
    ]
}
,
{
    _id : 2,
    finance: [
        {
            "k": "sales",
            "v": {
                "description":"sales over the year",
                v: 234000,
            }
        },
        {
            "k": "profit",
            "v": {
                "description": "money made from sales",
                v: 123123,
            }
        }
    ]
}
]

我可以为金融编制索引.k,但我很难构建一个聚合查询,将与特定键匹配的所有数字相加.这就是我最初 Select 命名属性的原因,但这确实需要在有数千个"k"标签的情况下工作.

有人知道如何使用新框架为此构建聚合查询吗?我试过这个;

db.projects.aggregate([
    {
        $match: {
            // QUERY
            $and: [
                // main query
                {},
            ]
        }
    },
    {
        $group: {
            _id: null,
            "numberOf": { $sum: 1 },
            "sales":    { $sum: "$finance.v.v" },
            "profit":   { $sum: "$finance.v.v" },
        }
    },
])

但我得到了;

{
    "errmsg" : "exception: can't convert from BSON type Array to double",
    "code" : 16005,
    "ok" : 0
}

**为了获得额外的荣誉,我还需要能够在MapReduce查询中实现这一点.

推荐答案

您可以使用聚合框架获得销售and利润and您可能存储在密钥/值对表示中的任何其他值.

对于您的示例数据:

var pipeline = [
    {
        "$unwind" : "$finance"
    },
    {
        "$group" : {
            "_id" : "$finance.k",
            "numberOf" : {
                "$sum" : 1
            },
            "total" : {
                "$sum" : "$finance.v.v"
            }
        }
    }
]

R = db.tb.aggregate( pipeline );
printjson(R);
{
        "result" : [
            {
                "_id" : "profit",
                "numberOf" : 2,
                "total" : 246246
            },
            {
                "_id" : "sales",
                "numberOf" : 2,
                "total" : 468000
            }
        ],
        "ok" : 1
}

如果您有额外的k/v对,那么您可以添加一个只通过["销售"、"利润"]中的k值的匹配项.

Mongodb相关问答推荐

在出现错误时忽略mongodb事务回滚是好做法吗

从MongoDB中的嵌套数组中提取找到的值及其索引

除非满足某个条件,否则Mongo是否按日期排序?

如何在MongoDB中搜索有序子集的方法?

仅当特定字段存在于 MongoDB 中时才更新它

来自嵌套对象数组的 MongoDB 聚合

使用 mongo-driver/mongo 使用键/值对中的值表达式查找文档

根据条件删除一些数组元素并将数组的大小更新为mongo中的另一个文件

MongoDB 聚合使用 $match 和 $expr 和数组

在mongoose 中按键查找嵌套对象

将 MongoDB BsonDocument 转换为字符串

解析命令行时出错:unrecognized option --rest

Meteor 方法与deny/allow 规则

从 MongoDB find() 结果集中识别最后一个文档

Springboot 使用 find*() 查询时出现 Mongodb 错误

.NET 中的 Mongodb 单元测试

如何在 mongoDB 中聚合巨大的数组?

在 mongodb 中插入当前日期时间

通过浏览器连接mongodb?

Pymongo/bson:将 python.cursor.Cursor 对象转换为可序列化/JSON 对象