我需要按型号对产品进行分组。每个产品都有模型字段-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
。
它可能还在某个地方,但我现在似乎找不到它:)
在该消息线程中,除了聚合框架不支持这一点之外,您的另一个选择(也是聚合的唯一实际选择)是使用mapReduce方法。例如:
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,而是定义一种替代形式的"手动引用",可以嵌入"集合"one_answers"数据库"信息,也可以根据需要在应用程序模式中依赖这些信息的外部定义。只要您遵循相同的规则,那么您就可以对任何具有有效属性名称的内容使用聚合框架。