猫鼬按字段分组和分组结果应存储为groupname:object

时间:2018-07-20 18:07:41

标签: mongodb mongoose

对于以下架构(伪代码)。

new mongoose.Schema({
      name: {type: String, unique: true},
      foo: {type: Number},
      bar: {type: Number, default: null},
}

正常结果将是.find():

[{
    _id: x
    name: 'Name1'
    foo: 1
    bar: 222
}, {
    _id: y
    name: 'Name2'
    foo: 1
    bar: 333
}, {
    _id: z
    name: 'Name3'
    foo: 2
    bar: 444
}];

我要返回按foo分组的结果,并且键应为foo的变量/数字:

[{
    '1': [{
        name: 'Name1'
        bar: 222
    }, {
        name: 'Name2'
        bar: 333
    }],
    '2': [{
        name: 'Name3'
        bar: 444
    }]
}]

我正在尝试使用aggregate,但是我始终无法用“ Number of Foo”替换_id。

猫鼬甚至有可能吗?还是我需要在Nodejs函数中编辑对象?

1 个答案:

答案 0 :(得分:0)

您可以尝试以下汇总:

db.col.aggregate([
    {
        $group: {
            _id: "$foo",
            obj: { $push: { name: "$name", bar: "$bar" } }
        }
    },
    {
        $replaceRoot: {
            newRoot: {
                $let: {
                    vars: { obj: [ { k: {$substr:["$_id", 0, -1 ]}, v: "$obj" } ] },
                    in: { $arrayToObject: "$$obj" }
                }
            }
        }
    }
])

输出:

{ "2" : [ { "name" : "Name3", "bar" : 444 } ] }
{ "1" : [ { "name" : "Name1", "bar" : 222 }, { "name" : "Name2", "bar" : 333 } ] }

$replaceRoot允许您在根级别定义新对象。要动态创建密钥,您需要$arrayToObject,它需要一个k-v对数组(在此使用$let定义)。要将int转换为字符串,可以在MongoDB v 4.0中将trick$substr{$substr:["$foo", 0, -1 ]})或$toString运算符一起使用