【发布时间】:2015-05-22 15:34:52
【问题描述】:
在 find() 查询中,您可以在第二个参数中隐藏带有 projection 文档的字段:
var cursor = collection.find(query, {
'_id': false,
'unwanted': false
});
它将返回文档中的任何字段和子文档。这是有道理的。
当您将此projection 文档放入aggregation pipeline 时,为什么规则会有所不同? $project 不一样:
var cursor = collection.aggregate([
{
$match : query
},
{
$project : {
'_id': false,
'unwanted': false
}
}
]);
问题:
exception: The top-level _id field is the only field currently supported
for exclusion
如何隐藏特定的子文档而不诉诸于明确包括我想要的所有字段?
编辑:除了一些索引字段外,文档有任意数量的字段,没有定义的架构。所以我无法指定我想要包含的内容,因为我不知道文档中会有哪些额外的字段。
想象具有随机字段的文档,_id 和 unwanted 子文档除外。我想删除这两个。
更新:
似乎这个问题不清楚,因为讨论的是逻辑而不是问题。所以让我来说明一个低效的解决方案:
// node.js
var cursor = collection.aggregate([
{
$match : query
},
// ...
]);
cursor.toArray(function(array){
for (var i = 0; i < array.length; i++) {
var document = array[i];
delete document._id;
delete document.unwanted;
}
})
我不喜欢这样,因为将cursor 渲染为array 会产生开销,并且限制为 16MB 大小的集合。此外,不必这样做正是投影文档的目的。
因此我的问题是,为什么我可以使用带有投影的find() 来获得我的光标,但不能使用带有相同投影的aggregate()?逻辑在哪里?该功能显然在 MongoDB 适配器中,否则它也不适用于 find()。除了我刚才提到的之外,还有哪些可能的解决方案或解决方法?
我认为一种解决方案可能是使用MongoDB 2.6 聚合函数$redact,但我无法弄清楚如何使用文档来简单地删除一个静态子文档。另外我不喜欢使用它,因为我们的大多数系统都运行MongoDB 2.4。
【问题讨论】:
-
Downvote 和 close 并不意味着在情感上使用,如果没有留下建设性的评论而投反对票是可悲的。我认为这是由移除自己的 cmets 的人完成的。无论您是否可以想象一个用例,为什么
find和aggregate似乎对同一阶段有不同的规则集显然是一个很好且难以回答的问题。
标签: mongodb aggregation-framework projection