我需要按型号分组的产品。每个产品都有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类型。
旧的一段读起来就像这条信息所示:
警告:管道无法对以下类型的值进行操作:Binary
、Symbol
、MinKey
、MaxKey
、DBRef
、Code
、CodeWScope
和{ "_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”信息,也可以在应用程序模式中依赖这些内容的外部定义。只要遵循相同的规则,就可以对任何具有有效属性名的对象使用聚合框架。