Значи си прав в това, че $pull
операторът прави точно това, което се казва в документацията, тъй като неговите аргументи всъщност са „заявка“, използвана за съвпадение на елементите, които трябва да бъдат премахнати.
Ако съдържанието на вашия масив винаги има елемента на "първа" позиция, както показвате, тогава $pop
операторът всъщност премахва този първи елемент.
С основния драйвер за възел:
collection.findOneAndUpdate(
{ "array.0": "bird" }, // "array.0" is matching the value of the "first" element
{ "$pop": { "array": -1 } },
{ "returnOriginal": false },
function(err,doc) {
}
);
С mongoose аргументът за връщане на модифицирания документ е различен:
MyModel.findOneAndUpdate(
{ "array.0": "bird" },
{ "$pop": { "array": -1 } },
{ "new": true },
function(err,doc) {
}
);
Но нито един от тях не е от голяма полза, ако позицията на масива на „първия“ елемент за премахване не е известна.
За общия подход тук се нуждаете от „две“ актуализации, като едната да съответства на първия елемент и да го замените с нещо уникално, което да бъде премахнато, а второто действително да премахне този модифициран елемент.
Това е много по-просто, ако се прилагат прости актуализации и не се иска върнатият документ, а също така може да се направи групово в различни документи. Също така помага да използвате нещо като async.series, за да избегнете вмъкването на вашите обаждания:
async.series(
[
function(callback) {
collection.update(
{ "array": "bird" },
{ "$unset": { "array.$": "" } },
{ "multi": true }
callback
);
},
function(callback) {
collection.update(
{ "array": null },
{ "$pull": { "array": null } },
{ "multi": true }
callback
);
}
],
function(err) {
// comes here when finished or on error
}
);
Така че с помощта на $unset
тук с позиционния $
оператор позволява на "първия" елемент да бъде променен на null
. След това последващата заявка с $pull
просто премахва всеки null
запис от масива.
По този начин можете безопасно да премахнете "първото" появяване на стойност от масив. Да се определи дали този масив съдържа повече от една стойност, която е една и съща, е друг въпрос.