在find()查询中,您可以使用第二个参数中的投影文档隐藏字段:
var cursor = collection.find(query, {
'_id': false,
'unwanted': false
});
它将返回文档中的任何字段和子文档.这是有道理的.
将此投影文档放入聚合管道时,为什么规则会有所不同? $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和不需要的子文档.我想删除这两个.
更新:
看来这个问题还不清楚,因为讨论的是逻辑而不是问题.那么让我来说明一个低效的解决方案:
// 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;
}
})
我不喜欢这样,因为将光标渲染到数组会产生开销,并且限制为16MB大小的集合.此外,不必执行此操作正是投影文档的用途.
因此我的问题是,为什么我可以使用带投影的find()来获得我的光标,但是不能使用具有相同投影的aggregate()?逻辑在哪里?该功能显然在MongoDB适配器中,否则它也不适用于find().除了刚刚提到的解决方案或解决方法之外,还有哪些可行的解决方案或解决方
我认为一个解决方案可能是使用MongoDB 2.6聚合函数$redact但我无法弄清楚如何使用文档如何简单地删除一个静态子文档.此外,我不想使用它,因为我们的大多数系统都运行MongoDB 2.4.
最佳答案 遗憾的是,您无法在聚合管道中执行此操作,并且在
documentation中已明确定义:
+-----------------------+---------------------------------------------------------+
| Syntax | Description |
+-----------------------+---------------------------------------------------------+
| <field>: <1 or true> | Specify the inclusion of a field. |
| _id: <0 or false> | Specify the suppression of the _id field. |
| <field>: <expression> | Add a new field or reset the value of an existing field. |
+-----------------------+---------------------------------------------------------+
唯一的出路就是你所描述的:
resorting to explicitly including all the fields I want
但无论如何,您可以通过动态构建$project文档来实现这一点,以防您拥有可能出现的所有可能字段.这是一个伪代码:
project_doc = {}
for field in fields
if field not in to_be_hidden_fields:
project_doc[field] = "$" + field
return {"$project": project_doc}
这是因为
If you specify an inclusion of a field that does not exist in the document,
$project
ignores that field inclusion; i.e.$project
does not add the field to the document.
然后只需将生成的$project阶段添加到聚合管道中.
但是如果您事先不了解架构,或者甚至不知道生成的文档可能包含的所有可能字段,我认为您应该重新考虑设计.
无论如何,另一个问题出现了,如果你不了解这些字段,你将如何进行聚合?我认为这就是为什么MongoDB消除了$project中的字段排除功能的原因.