Удаление последнего документа из БД Mongo одним запросом - PullRequest
0 голосов
/ 28 мая 2018

Я хочу удалить самый последний документ из моей MongoDB одним запросом.

Я пробовал некоторые команды, но они, похоже, не работают.

Ответы [ 2 ]

0 голосов
/ 02 мая 2019

очень просто:

Model.findOneAndDelete({},{"sort": { "_id": -1 }})
0 голосов
/ 29 мая 2018

Основная операция, которую вы ищете - это findOneAndDelete() в mongoose, которая является атомарной операцией, возвращающей «удаленный» документ с ответом.Это влияет только на один документ, и вы получаете «последний», применяя в опциях спецификацию сортировки.

У вас, в основном, есть два варианта «последнего», либо по полю, содержащему дату BSON »«свойство, которое вы сохранили в документах, по которым вы можете сортировать:

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

или с помощью поля _id, где использовался ObjectId, так как без какого-либо другого вмешательства это значение будет« всегда увеличиваться »«с каждым вставленным документом:

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

Как правило, это ваш вариант, если вы не сохранили поле в документе с датой BSON в качестве средства определения« последней вставленной »или« последней измененной ».Если вы хотите «последний измененный», тогда у вас действительно нет другого варианта, чтобы записать такое свойство даты BSON в документе, так как сам _id является неизменным и не изменяется, и в лучшем случае является «запасным» для «созданного»date », когда вы явно не сохранили никакое другое поле для записи такой информации.

Ниже приведен полный пример, который демонстрирует добавление нескольких документов в коллекцию и затем« удаление »только« последнего »документа, соответствующего предоставленному запросу.критерии.Показаны как сохраненная дата, так и поле _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
    }
  ]
}

NOTE : Для фактического драйвера узла это findOneAndDelete(), по сути, идентично и является фактическим вызовом, сделанным mongoose к серверу, но более старые версии mongoose поддерживают только findOneAndRemove(), что почтиидентичны по параметрам, но вместо этого выдают запрос findAndModify() через базовый API.

С технической точки зрения это все на самом деле команда findAndModify, однако онаОбычно предпочтительнее использовать современный API, поскольку методы имеют «ясность» по своему прямому назначению, а также выбирают разумные «значения по умолчанию» для диапазона доступных параметров для более широкой «команды», которую фактически обрабатывает сервер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...