简体   繁体   English

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

[英]How to delete documents returned by an aggregation query in mongodb

I am attempting to delete all the documents returned by an aggregation in Mongodb.我正在尝试删除 Mongodb 中的聚合返回的所有文档。

The query I have is as follows:我的查询如下:

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({});
  });

I tried this query but it removes all the data in the database, any suggestions please?我试过这个查询,但它删除了数据库中的所有数据,请问有什么建议吗?

Since the remove doesn't have a query condition its going to match with all the documents and delete irrespective of the aggregation result.由于删除没有查询条件,因此无论聚合结果如何,它都会与所有文档匹配并删除。

Solution (match the ids of the current cursor doc):解决方案(匹配当前cursor doc的ids):

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 });
  });

Another better solution would be to have single round trip to db while deletion is get a list of ids from the aggregation cursor() via cursor.map()另一个更好的解决方案是在删除时通过cursor.map()从聚合cursor()获取 id 列表

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 } });

As per your query its not required to filter by aggregation and remove by another methods, you can apply this query filters in remove() method's filters,根据您的查询,它不需要按聚合过滤并通过其他方法删除,您可以在remove()方法的过滤器中应用此查询过滤器,

  • the $expr Allows the use of aggregation expressions within the query language, $expr允许在查询语言中使用聚合表达式,
db.getCollection("Collection").remove({ 
  $and: [
    { status: { $in: ["inserted", "done", "duplicated", "error"] } },
    {
      $expr: {
        $eq: [
          { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
          "2019-08-06"
        ]
      }
    }
  ]
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM