A operação básica que você está procurando é
findOneAndDelete()
em mangusto que é uma operação atômica retornando o documento "removido" com a resposta. Isso afeta apenas um único documento e você obtém o "último" aplicando uma especificação de classificação nas opções. Você basicamente tem duas opções para "último", seja por um campo contendo uma propriedade "data" BSON que você armazenou nos documentos que você pode classificar:
Model.findOneAndDelete(
{ "field": "a" },
{ "sort": { "date": -1 } }
)
Ou usando o
_id
campo onde um ObjectId
foi usado, pois sem qualquer outra intervenção esse valor "sempre aumentará" a cada documento inserido:Model.findOneAndDelete(
{ "field": "a" },
{ "sort": { "_id": -1 } }
)
Geralmente, essa é sua opção se você não armazenou um campo no documento com uma data BSON como meio de determinar a "última inserção" ou "última modificação". Se você quiser "última modificação", então você realmente não tem outra opção para registrar uma propriedade de data BSON no documento, pois o
_id
em si é imutável e não muda e, na melhor das hipóteses, é um "retorno" para uma "data de criação" quando você não armazenou explicitamente nenhum outro campo para registrar essas informações. Segue um exemplo completo, que demonstra a adição de vários documentos a uma coleção e, em seguida, a "remoção" apenas do "último" documento que atende aos critérios de consulta fornecidos. Ambos usando uma data armazenada e o
_id
campo são demonstrados: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()
}
})()
E isso retorna a saída esperada de:
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
}
]
}