Takže v tom $pull
máte pravdu Operátor dělá přesně to, co říká dokumentace, protože jeho argumenty jsou ve skutečnosti "dotaz", který se používá ke shodě prvků, které mají být odstraněny.
Pokud obsah pole náhodou měl prvek vždy na "první" pozici, jak ukazujete, pak $pop
operátor ve skutečnosti tento první prvek odstraní.
Se základním ovladačem uzlu:
collection.findOneAndUpdate(
{ "array.0": "bird" }, // "array.0" is matching the value of the "first" element
{ "$pop": { "array": -1 } },
{ "returnOriginal": false },
function(err,doc) {
}
);
U mongoose je argument pro vrácení upraveného dokumentu jiný:
MyModel.findOneAndUpdate(
{ "array.0": "bird" },
{ "$pop": { "array": -1 } },
{ "new": true },
function(err,doc) {
}
);
Ale ani jedno není moc užitečné, pokud není známa pozice pole „první“ položky, kterou chcete odstranit.
Pro obecný přístup zde potřebujete „dvě“ aktualizace, přičemž jedna bude odpovídat první položce a nahradí ji něčím jedinečným, co má být odstraněno, a druhá, která skutečně odstraní tuto upravenou položku.
To je mnohem jednodušší, pokud použijete jednoduché aktualizace a nežádáte o vrácený dokument, a lze to také provést hromadně napříč dokumenty. Pomáhá také použít něco jako async.series, abyste se vyhnuli vnoření hovorů:
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
}
);
Takže pomocí $unset
zde s pozičním $
operátor umožňuje změnit "první" položku na null
. Poté následuje dotaz s $pull
pouze odstraní všechny null
vstup z pole.
Takto bezpečně odstraníte „první“ výskyt hodnoty z pole. Jiná otázka je určit, zda toto pole obsahuje více než jednu hodnotu, která je stejná.