sql >> Database teknologi >  >> NoSQL >> MongoDB

Fjerner seneste dokument fra Mongo DB i en enkelt forespørgsel

Den grundlæggende handling, du leder efter, er findOneAndDelete() i mongoose, som er en atomoperation, der returnerer det "fjernede" dokument med svaret. Dette påvirker kun et enkelt dokument, og du får det "sidste" ved at anvende en sorteringsspecifikation i valgmulighederne.

Du har grundlæggende to muligheder for "sidste", enten ved et felt, der indeholder en BSON "dato" egenskab, du har gemt i dokumenterne, som du kan sortere på:

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

Eller ved at bruge _id felt, hvor et ObjectId blev brugt, da uden nogen anden indgriben vil denne værdi "altid stige" med hvert indsat dokument:

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

Det er generelt din mulighed, hvis du ikke har gemt et felt i dokumentet med en BSON-dato som et middel til at bestemme "senest indsat" eller "sidst ændret". Hvis du vil have "sidst ændret", har du virkelig ingen anden mulighed end at registrere en sådan BSON-datoegenskab i dokumentet siden _id i sig selv er uforanderlig og ændrer sig ikke, og i bedste fald er det en "tilbagegang" for en "oprettet dato", når du ikke eksplicit har gemt noget andet felt til at registrere sådanne oplysninger.

Et komplet eksempel følger, som demonstrerer tilføjelse af flere dokumenter til en samling og derefter "fjernelse" af kun det "sidste" dokument, der opfylder de angivne forespørgselskriterier. Både ved at bruge en gemt dato og _id felt er demonstreret:

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()
  }

})()

Og dette returnerer det forventede output af:

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


  1. Opsætning af flere Docker-containere og MongoDB til at køre i CircleCI

  2. MongoDB Multiple Masters i ReplicaSet

  3. Jobplanlægning i MongoDB

  4. Fjern et underdokument indlejret i et array i MongoDB