mongodb 聚合与 $project 有条件地排除一个字段

Posted

技术标签:

【中文标题】mongodb 聚合与 $project 有条件地排除一个字段【英文标题】:mongodb aggregation with $project to conditionally exclude a field 【发布时间】:2015-03-25 01:06:05 【问题描述】:

我想从 mongo db aggergtion 管道中排除一个字段,在阅读了文档后,我认为我需要指定 1 或 0 来保留该字段(参见http://docs.mongodb.org/manual/reference/operator/aggregation/project/)

所以我尝试了以下(使用node.js mongoose,但语法与普通mongo完全一样):

aggregate.match( date:  $gte : today  );
aggregate.sort('-date');
aggregate.group(
    _id: '$name',
    date:  $first: '$date' ,
    user:  $first: '$user' ,
    app:  $first: '$app' 
);
aggregate.project(
    _id: 1,
    last:  $cond: [  $eq : [ '$_id', 'undo' ] , '$date', 0 ] ,
    user:  $cond: [  $eq : [ '$_id', 'undo' ] , '$user', 0 ] ,
    app:  $cond: [  $eq : [ '$_id', 'undo' ] , '$app', 0 ] 
);

但是这样做,我会以这样的文件结束:

[ 
  
    _id: 'devices',
    user: 0,
    app: 0,
    last: 0
  ,
   
    _id: 'undo',
    user: 'test',
    app: 'truc',
    last: Mon Jan 26 2015 16:21:53 GMT+0100 (CET)
  
]

我希望 userappdate 仅在 _idundo 时出现。

如何实现?

谢谢!

【问题讨论】:

【参考方案1】:

我认为这还不可能。

尝试排除非 _id 字段时来自 shell 的错误消息:

The top-level _id field is the only field currently supported for exclusion

【讨论】:

【参考方案2】:

从 mongoDB 3.6 开始,您可以使用the REMOVE variable 有条件地排除字段。

在您的特定情况下,项目阶段应如下所示:

aggregate.project(
    _id: 1,
    last:  $cond: [  $eq : [ '$_id', 'undo' ] , '$date', '$$REMOVE' ] ,
    user:  $cond: [  $eq : [ '$_id', 'undo' ] , '$user', '$$REMOVE' ] ,
    app:  $cond: [  $eq : [ '$_id', 'undo' ] , '$app', '$$REMOVE' ] 
);

【讨论】:

以上是关于mongodb 聚合与 $project 有条件地排除一个字段的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 $project 中提供的 _id 与 mongodb 聚合进行 $match?

MongoDB 聚合管道(Aggregation Pipeline)

if else if cond in mongodb 聚合

如何在 MongoDB 中有条件地显示/隐藏字段

MongoDB 查找与使用聚合指定的任何条件匹配的文档

$element 匹配或 $unwind 与 AND/Multiple 条件与 mongoDB 聚合