我需要按型号分组产品。每个产品都有模型字段 - 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("....")
}
}
答案 0 :(得分:3)
手册中曾经有一节明确指出聚合框架下不支持DBRef,以及其他各种BSON类型。
旧段落如此google groups archive消息所示:
警告:管道无法对以下类型的值进行操作:
Binary
,Symbol
,MinKey
,MaxKey
,{{1 }},DBRef
和Code
。
它可能仍然存在于某处,但我现在似乎无法找到它:)
另外,在该消息线程中,除了聚合框架中不支持的情况之外,您的其他选项(并且仅用于聚合的实际选项)是使用mapReduce方法。作为shell示例:
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 } }
)
结构,它看起来不太好,但它确实允许你正在寻找的那种聚合。
还提到了这个JIRA问题:SERVER-14466,但我不会坚持这方面的大量动作。
所以你可以使用mapReduce但是建议不要使用DBRef并定义一种替代形式的“手动引用”,要么嵌入“集合”和“数据库”信息,要么依赖于应用程序中外部定义的东西。架构,取决于您的需求。只要您遵循相同的规则,就可以将聚合框架用于具有有效属性名称的任何内容。