Mongodb 按 dbref 字段分组

Mongodb group by dbref field

我需要按型号分组产品。每个产品都有模型字段 - DBRef 到模型集合。我尝试使用此聚合查询,但出现错误 FieldPath field names may not start with '$'.

聚合查询:

db.Products.aggregate([
    { $project: { _id: 0, model: 1, isActive: 1 } },
    { $group: { _id: "$model.$id", actives: { $push: "$isActive" } }}
]);

产品文档示例:

{
    _id: ObjectId("54f48610e31701d2184dede5"),
    isActive: true,
    model: {
        $db: "database",
        $ref: "Models",
        $id: ObjectId("....")
    }
}

手册中曾经有一个部分明确指出聚合框架不支持 DBRef,以及其他各种 BSON 类型。

旧段落如 google groups archive 消息所示:

Warning: The pipeline cannot operate on values of the following types: Binary, Symbol, MinKey, MaxKey, DBRef, Code, and CodeWScope.

它可能还在某个地方,但我现在似乎找不到它:)

此外,正如该消息线程中提到的那样,除了聚合框架不支持这一点之外,您的另一个选择(也是唯一真正的聚合选项)是使用 mapReduce 方法。作为 shell 示例:

db.Products.mapReduce(
    function() {
        emit( this.model.$id, { "actives": [this.isActive] } );
    },
    function(key,values) {
        var result = { "actives": [] };
        values.forEach(function(value) {
            value.actives.forEach(function(active) {
                result.actives.push( active );
            });
        });
    },
    { "out": { "inline": 1 } }
)

由于 mapReduce 结果的任意 { "_id": "", "value": { } } 结构,它看起来不太好,但它确实允许您正在寻找的那种聚合。

也提到了这个 JIRA 问题:SERVER-14466,但我不会在这方面坚持太多行动。

因此您可以使用 mapReduce,但建议不要使用 DBRef 并定义 "manual references" 的替代形式,嵌入 "collection" 和 "database" 信息或依赖外部根据您的需要,在您的应用程序模式中定义此类内容。只要您遵循相同的规则,您就可以将聚合框架用于任何具有有效 属性 名称的内容。