删除mongodb $ lookup聚合的结果

时间:2017-06-13 08:08:35

标签: mongodb aggregation-framework

如何删除因此聚合而返回的所有chunks文档?

db.getCollection('chunks').aggregate([
    {
      $lookup:
        {
          from: "files",
          localField: "files_id",
          foreignField: "_id",
          as: "file"
        }
   },
   {
     $match:
       {
         "file.uploadDate":
           {
             $lt: ISODate("2017-06-10T00:00:00.000Z")
           }
       }
   }
])

我的架构有一个名为files的集合,其中包含文件元数据(name,uploadDate)和块,其中包含实际数据(binary,files_id)

我知道db.collection.deleteMany({})但是它只接受匹配过滤器。

我有MongoDB 3.2

2 个答案:

答案 0 :(得分:3)

循环结果:

var ops = [];

db.getCollection('chunks').aggregate([
    {
      $lookup:
        {
          from: "files",
          localField: "files_id",
          foreignField: "_id",
          as: "file"
        }
   },
   {
     $match:
       {
         "file.uploadDate":
           {
             $lt: ISODate("2017-06-10T00:00:00.000Z")
           }
       }
   }
]).forEach(doc => {
  ops = [
    ...ops,
    { "deleteOne": {
       "filter": { "_id": doc._id }   
    }}
  ];
  if ( ops.length >= 1000 ) {
    db.getCollection('chunks').bulkWrite(ops);
    ops = [];
  }
});

if ( ops.length > 0 ) {
  db.getCollection('chunks').bulkWrite(ops);
  ops = [];
}

或者在没有ES6的环境中:

var ops = [];

db.getCollection('chunks').aggregate([
    {
      $lookup:
        {
          from: "files",
          localField: "files_id",
          foreignField: "_id",
          as: "file"
        }
   },
   {
     $match:
       {
         "file.uploadDate":
           {
             $lt: ISODate("2017-06-10T00:00:00.000Z")
           }
       }
   }
]).forEach(function(doc) {

  ops.push({ "deleteOne": { "filter": { "_id": doc._id }  } });

  if ( ops.length >= 1000 ) {
    db.getCollection('chunks').bulkWrite(ops);
    ops = [];
  }
});

if ( ops.length > 0 ) {
  db.getCollection('chunks').bulkWrite(ops);
  ops = [];
}

使用.bulkWrite()然后你基本上“批量”处理大量1000个请求。因此,数据库的实际写入和响应仅在时间发生,而不是所有条目。

您无法提供聚合管道作为常规.remove**()方法的查询参数。所以你要做的就是用这样的动作循环光标。

答案 1 :(得分:2)

获得汇总结果后,您可以使用map函数获取所有chunk ID ,然后将db.collection.remove()$in运算符一起使用

var pipeline = [
  {$lookup:{
      from: "files",
      localField: "files_id",
      foreignField: "_id",
      as: "file"
    }
  },
  {$match:{
      "file.uploadDate":
      {
        $lt: ISODate("2017-06-10T00:00:00.000Z")
      }
    }
  }
];

var cursor = db.chunks.aggregate(pipeline);
var chunkIds = cursor.map(function (chunk) { return chunk._id; });
db.chunks.remove({"_id": { "$in": chunkIds }});