我需要按型号分组的产品。每个产品都有model field-dbref to models集合。我尝试使用此聚合查询,但有错误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类型。
旧的一段读起来就像这条信息所示:
警告:管道无法对以下类型的值进行操作:BinarySymbolMinKeyMaxKeyDBRefCodeCodeWScope{ "_id": "", "value": { } }
它可能还在某处,但我现在似乎找不到:)
消息线程中的另一个优点是,除了聚合框架中不支持此功能外,您的另一个选项(也是聚合的唯一实际选项)是改用google groups archive方法。作为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结果的任意结构,它看起来不太好,但它确实允许您正在寻找的那种聚合。
也有人提到这个吉拉问题:mapReduce,但我不会坚持在这方面有太多的行动。
因此,您可以使用mapreduce,但建议您不要使用dbref,而是根据您的需要,定义一种替代形式的“手动引用”,可以嵌入“collection”和“database”信息,也可以在应用程序模式中依赖这些内容的外部定义。只要遵循相同的规则,就可以对任何具有有效属性名的对象使用聚合框架。

09-15 12:46