在单个查询中从Mongo DB中删除最新文档

时间:2018-05-28 13:59:54

标签: node.js mongodb mongoose mongodb-query

我想在一次查询中删除MongoDB中的最新文档。

我尝试了一些命令,但它们似乎无法正常工作。

2 个答案:

答案 0 :(得分:3)

你正在寻找的基本操作是mongoose中的findOneAndDelete(),这是一个原子操作,返回"删除"文件与回应。这只会影响一个单独的文档而你会得到最后一个"通过在选项中应用排序规范。

然后你基本上有两个选项#34; last",或者是一个包含BSON" date"的字段。您存储在可以排序的文档中的属性:

_id

或者使用ObjectId字段,其中使用了Model.findOneAndDelete( { "field": "a" }, { "sort": { "_id": -1 } } ) ,因为没有任何其他干预,此值将始终增加"每个插入的文档:

_id

如果您没有使用BSON日期在文档中存储字段作为确定最近插入的"最新插入的字段,那么这通常是您的选择。或者"最后修改"。如果你想要"最后修改"那么你真的没有其他选择在文档中记录这样的BSON日期属性,因为_id本身是不可变的并且不会改变,并且充其量只是一个"后退"对于"创建日期"当您没有明确存储任何其他字段来记录此类信息时。

下面是一个完整的示例,演示了如何将多个文档添加到集合中,然后"删除"只有"最后"符合提供的查询条件的文档。使用存储日期和const { Schema } = mongoose = require('mongoose'); const uri = 'mongodb://localhost/test'; mongoose.Promise = global.Promise; mongoose.set('debug', true); const testSchema = new Schema({ field: String, other: String, date: Date }); const Test = mongoose.model('Test', testSchema); const log = data => console.log(JSON.stringify(data, undefined, 2)); (async function() { const now = Date.now(); const today = now - (now % (1000 * 60 * 60 * 24)); try { const conn = await mongoose.connect(uri); await Promise.all(Object.entries(conn.models).map(([k,m]) => m.remove())); await Test.insertMany([ ...[ ...Array(4)].map((e,i) => ({ field: "a", ...(i === 3) ? { other: "last" } : (i === 2) ? { other: "second last" } : {}, date: new Date(today + (i * 1000 * 60 * 60 * 24)) }) ), { field: "b", date: new Date(today + (5 * 1000 * 60 * 60 * 24)) } ]); let removed = await Test.findOneAndDelete( { field: "a" }, { sort: { "date": -1 } } ); log({ removed }); let remaining = await Test.find(); log({ remaining }); let next_removed = await Test.findOneAndDelete( { field: "a" }, { sort: { "_id": -1 } } ); log({ next_removed }); let still_remaining = await Test.find(); log({ still_remaining }); mongoose.disconnect(); } catch(e) { console.error(e) } finally { process.exit() } })() 字段都进行了演示:

Mongoose: tests.remove({}, {})
Mongoose: tests.insertMany([ { _id: 5b0cb4a60cf8000c7ebd4402, field: 'a', date: 2018-05-29T00:00:00.000Z, __v: 0 }, { _id: 5b0cb4a60cf8000c7ebd4403, field: 'a', date: 2018-05-30T00:00:00.000Z, __v: 0 }, { _id: 5b0cb4a60cf8000c7ebd4404, field: 'a', other: 'second last', date: 2018-05-31T00:00:00.000Z, __v: 0 }, { _id: 5b0cb4a60cf8000c7ebd4405, field: 'a', other: 'last', date: 2018-06-01T00:00:00.000Z, __v: 0 }, { _id: 5b0cb4a60cf8000c7ebd4406, field: 'b', date: 2018-06-03T00:00:00.000Z, __v: 0 } ], {})
Mongoose: tests.findOneAndDelete({ field: 'a' }, { sort: { date: -1 } })
{
  "removed": {
    "_id": "5b0cb4a60cf8000c7ebd4405",
    "field": "a",
    "other": "last",
    "date": "2018-06-01T00:00:00.000Z",
    "__v": 0
  }
}
Mongoose: tests.find({}, { fields: {} })
{
  "remaining": [
    {
      "_id": "5b0cb4a60cf8000c7ebd4402",
      "field": "a",
      "date": "2018-05-29T00:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5b0cb4a60cf8000c7ebd4403",
      "field": "a",
      "date": "2018-05-30T00:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5b0cb4a60cf8000c7ebd4404",
      "field": "a",
      "other": "second last",
      "date": "2018-05-31T00:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5b0cb4a60cf8000c7ebd4406",
      "field": "b",
      "date": "2018-06-03T00:00:00.000Z",
      "__v": 0
    }
  ]
}
Mongoose: tests.findOneAndDelete({ field: 'a' }, { sort: { _id: -1 } })
{
  "next_removed": {
    "_id": "5b0cb4a60cf8000c7ebd4404",
    "field": "a",
    "other": "second last",
    "date": "2018-05-31T00:00:00.000Z",
    "__v": 0
  }
}
Mongoose: tests.find({}, { fields: {} })
{
  "still_remaining": [
    {
      "_id": "5b0cb4a60cf8000c7ebd4402",
      "field": "a",
      "date": "2018-05-29T00:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5b0cb4a60cf8000c7ebd4403",
      "field": "a",
      "date": "2018-05-30T00:00:00.000Z",
      "__v": 0
    },
    {
      "_id": "5b0cb4a60cf8000c7ebd4406",
      "field": "b",
      "date": "2018-06-03T00:00:00.000Z",
      "__v": 0
    }
  ]
}

这会返回预期的输出:

Start_time
  

注意:对于实际的节点驱动程序,findOneAndDelete()基本相同,是mongoose对服务器的实际调用,但旧版本的mongoose仅支持{ {3}}在选项中几乎相同,但通过核心API发出findOneAndRemove()请求。

     

从技术角度来看,这些实际上都是findAndModify()命令,但是通常首选使用现代API,因为这些方法具有清晰度"在他们的预期目的,并选择合理的"默认"更广泛的"命令的可用选项范围"服务器实际处理的内容。

答案 1 :(得分:0)

非常简单:

import torch
x = torch.randn(1024,100)
y = torch.randn(1024,100)

%timeit torch.sqrt((x - y).pow(2).sum(1))
%timeit torch.norm(x - y, 2, 1)

#outputs
129 µs ± 1.79 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
291 µs ± 17.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)