つまり、 $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) {
}
);
マングースでは、変更されたドキュメントを返す引数が異なります:
MyModel.findOneAndUpdate(
{ "array.0": "bird" },
{ "$pop": { "array": -1 } },
{ "new": true },
function(err,doc) {
}
);
ただし、削除する「最初の」アイテムの配列位置がわからない場合は、どちらもあまり役に立ちません。
ここでの一般的なアプローチでは、「2つの」更新が必要です。1つは最初のアイテムに一致し、それを削除する一意のアイテムに置き換え、2つ目はその変更されたアイテムを実際に削除します。
これは、単純な更新を適用し、返されたドキュメントを要求しない場合ははるかに簡単であり、ドキュメント間で一括して実行することもできます。また、呼び出しのネストを回避するために、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
を削除するだけです 配列からのエントリ。
これが、値の「最初の」出現を配列から安全に削除する方法です。別の質問ですが、その配列に同じ値が複数含まれているかどうかを判断するには。