在单个查询中从Mongo DB删除最新文档 [英] Removing Latest document from Mongo DB in single query

查看:52
本文介绍了在单个查询中从Mongo DB删除最新文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过一次查询从MongoDB中删除最新文档.

I want to delete the latest document from my MongoDB in a single query.

我尝试了一些命令,但是它们似乎不起作用.

I have tried some commands but they doesn't seem to work.

推荐答案

您正在寻找的基本操作是

The basic operation you are looking for is findOneAndDelete() in mongoose which is an atomic operation returning the "removed" document with the response. This only ever affects a single document and you get the "last" by applying a sort specification in the options.

然后,您基本上有两个"last"选项,一个是通过包含您存储在文档中的BSON"date"属性的字段进行分类的:

You basically then have two options for "last", either being by a field containing a BSON "date" property you have stored in the documents which you can sort on:

Model.findOneAndDelete(
   { "field": "a" },
   { "sort": { "date": -1 } }
)

或通过使用使用ObjectId_id字段,因为在没有任何其他干预的情况下,此值将随插入的每个文档始终增加":

Or by using the _idfield where an ObjectId was used, as without any other intervention this value will "always increase" with every inserted document:

Model.findOneAndDelete(
   { "field": "a" },
   { "sort": { "_id": -1 } }
)

如果您没有在文档中存储带有BSON日期的字段作为确定最新插入"或最后修改"的方式,通常这是您的选择.如果您要最后修改",那么您真的没有其他选择可以在文档中记录这样的BSON日期属性,因为_id本身是不可变的,不会改变,充其量是创建"的后备"日期",则您没有明确存储任何其他字段来记录此类信息.

That's generally your option if you did not store a field within the document with a BSON Date as a means of determining the "latest inserted" or "last modified". If you want "last modified" then you really have no other option that to record such a BSON date property within the document since the _id itself is immutable and does not change, and at best is a "fallback" for a "created date" when you did not explicitly store any other field to record such information.

下面是一个完整的示例,该示例演示将多个文档添加到集合中,然后仅删除"满足所提供查询条件的最后一个"文档.演示了使用存储的日期和_id字段:

A full example follows, which demonstrates adding multiple documents to a collection and then "removing" only the "last" document meeting the supplied query criteria. Both using a stored date and the _id field are demonstrated:

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
    }
  ]
}

注意:对于实际的节点驱动程序,它是 findOneAndDelete() 本质上是相同的,是猫鼬对服务器的实际调用,但是猫鼬的旧版本仅支持

NOTE: For the actual Node Driver it's findOneAndDelete() is essentially identical and is the actual call made by mongoose to the server, but older versions of mongoose only support findOneAndRemove() which is almost identical in options but instead issues a findAndModify() request through the core API.

从技术角度来看,这些实际上都是 findAndModify 命令,但是通常首选使用现代API,因为这些方法在其预期用途中具有明确性",并且还可以为服务器实际处理的更广泛的命令"的可用选项范围选择合理的默认值". /p>

From a technical standpoint these are all actually the findAndModify command, however it is generally preferred to use the modern API since the methods have "clarity" in their intended purpose, and also choose reasonable "defaults" to the range of available options to the broader "command" which the server actually processes.

这篇关于在单个查询中从Mongo DB删除最新文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆