如何在MongoDB中删除聚合查询返回的文档

14

我正在尝试删除Mongodb聚合返回的所有文档。

我的查询如下:

db.getCollection("Collection")
  .aggregate([
    {
      $match: { status: { $in: ["inserted", "done", "duplicated", "error"] } }
    },
    {
      $project: {
        yearMonthDay: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }
      }
    },  
    { $match: { yearMonthDay: { $eq: "2019-08-06" } } }
  ])
  .forEach(function(doc) {
    db.getCollection("Collection").remove({});
  });

我尝试了这个查询,但它删除了数据库中的所有数据,有什么建议吗?

3个回答

30

由于 remove 操作没有查询条件,它会匹配所有文档并删除,而不考虑聚合结果。

解决方案(匹配当前游标文档的 ID):

db.getCollection("Collection")
  .aggregate([
    {
      $match: { status: { $in: ["inserted", "done", "duplicated", "error"] } }
    },
    {
      $project: {
        yearMonthDay: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }
      }
    },
    { $match: { yearMonthDay: { $eq: "2019-08-06" } } }
  ])
  .forEach(function(doc) {
    db.getCollection("Collection").remove({ "_id": doc._id });
  });

另一个更好的解决方案是,在删除时从聚合cursor()通过cursor.map()获取ID列表,只需进行一次单向DB往返。

var idsList = db
  .getCollection("Collection")
  .aggregate([
    {
      $match: { status: { $in: ["inserted", "done", "duplicated", "error"] } }
    },
    {
      $project: {
        yearMonthDay: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }
      }
    },
    { $match: { yearMonthDay: { $eq: "2019-08-06" } } }
  ])
  .map(function(d) {
    return d._id;
  });

//now delete those documents via $in operator
db.getCollection("Collection").remove({ _id: { $in: idsList } });

谢谢您的回答,我会尝试一下,然后再联系您。 - user11459242
1
谢谢,它有效。我还有一个问题,请问我可以使用JS文件执行第二个吗? - user11459242
谢谢,但我必须提到连接字符串到Mongo,还是只放这段代码? - user11459242
你可以直接从Mongo shell执行JS文件,但我感觉这不是你想要的,你可能希望在node.js或其他地方运行此代码。那么,连接字符串和集合实例等都是必需的。请参考此链接:https://mongodb.github.io/node-mongodb-native/3.3/ - ambianBeing
看,我创建了两个文件,file.js文件中放置了您的第二个建议,script.sh包含mongo < file.js。我的问题是:我必须在js文件中提到ConnectionString吗? - user11459242
显示剩余5条评论

5
根据您的查询,不需要通过聚合过滤并使用其他方法进行删除,您可以将此查询过滤器应用于remove()方法的过滤器中。 $expr允许在查询语言中使用聚合表达式。
db.getCollection("Collection").remove({ 
  $and: [
    { status: { $in: ["inserted", "done", "duplicated", "error"] } },
    {
      $expr: {
        $eq: [
          { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
          "2019-08-06"
        ]
      }
    }
  ]
});

这也可以支持deleteOnedeleteMany方法。


0
你可以在你的文档中添加expires,并在聚合的$merge阶段更新这个字段。
// 1) add this to your schema
deleteAt: {
  type: Date,
  expires: 0,
}

// 2) set the value of `deleteAt` for the documents to be deleted

// 3) add this at the end of the aggregation 
$merge: {
  into: "Collections" // or "Collection"
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接