Dus je hebt gelijk dat de $pull
operator doet precies wat de documentatie zegt, namelijk dat de argumenten in feite een "query" zijn die wordt gebruikt om de elementen te matchen die moeten worden verwijderd.
Als uw array-inhoud altijd het element op de "eerste" positie heeft, zoals u laat zien, dan is de $pop
operator verwijdert in feite dat eerste element.
Met de basis node driver:
collection.findOneAndUpdate(
{ "array.0": "bird" }, // "array.0" is matching the value of the "first" element
{ "$pop": { "array": -1 } },
{ "returnOriginal": false },
function(err,doc) {
}
);
Bij mangoest is het argument om het gewijzigde document terug te sturen anders:
MyModel.findOneAndUpdate(
{ "array.0": "bird" },
{ "$pop": { "array": -1 } },
{ "new": true },
function(err,doc) {
}
);
Maar geen van beide heeft veel zin als de arraypositie van het "eerste" item dat moet worden verwijderd niet bekend is.
Voor de algemene benadering hier heb je "twee" updates nodig, een om het eerste item te matchen en te vervangen door iets unieks om te verwijderen, en de tweede om dat gewijzigde item daadwerkelijk te verwijderen.
Dit is een stuk eenvoudiger als u eenvoudige updates toepast en niet om het geretourneerde document vraagt, en het kan ook in bulk over documenten worden gedaan. Het helpt ook om iets als async.series te gebruiken om te voorkomen dat uw oproepen worden genest:
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
}
);
Dus met behulp van de $unset
hier met de positionele $
operator staat toe dat het "eerste" item wordt gewijzigd in null
. Dan de volgende vraag met $pull
verwijdert gewoon elke null
invoer uit de array.
Zo verwijder je het "eerste" voorkomen van een waarde veilig uit een array. Om te bepalen of die array meer dan één waarde bevat die hetzelfde is, is echter een andere vraag.