MongoDBには$push
があります 演算子と$addToSet
演算子、どちらも非常によく似た処理を行います。
どちらの演算子も、既存の配列に値を追加します。主な違いは、追加しようとしている値がすでに含まれている配列を処理する方法と、使用できる修飾子にあります。
違い
既存の値 | 値が配列にすでに存在する場合は、 $ push 引き続き値を追加します(結果として値が重複します)。 ただし、 $ addToSet 値がまだ配列に存在しない場合にのみ値を追加します。したがって、値がすでに存在する場合は、 $ addToSet 追加しません(何もしません)。 |
修飾子 | $ push 演算子は、 $ sort などの追加の修飾子とともに使用できます。 、$スライスコード> 、および |
既存の値
次のドキュメントを含むコレクションがあるとします。
db.players.find()
結果:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5 ] }
$ addToSet
を使用しましょう 配列の1つに値を追加しようとします。
db.players.update(
{ _id: 3 },
{ $addToSet: { scores: 5 } }
)
出力:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
これは、一致するドキュメント(ドキュメント3)があったが、変更されていないことを示しています。挿入しようとした値( 5
)のため、変更されませんでした )はすでにアレイに存在します。
コレクションを見てみましょう:
db.players.find()
結果:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5 ] }
予想どおり、ドキュメント3は変更されていません。
$ push
を試してみましょう 代わりに:
db.players.update(
{ _id: 3 },
{ $push: { scores: 5 } }
)
出力:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
今回は、ドキュメントが変更されたことがわかります。
コレクションをもう一度確認することで、これを確認できます:
db.products.find()
結果:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5, 5 ] }
修飾子
$ push
演算子は、 $ position
などの修飾子とともに使用できます 、 $ sort
、および $ sense
。
$ addToSet
これらの修飾子と一緒に演算子を使用することはできません。
これらの修飾子を$addToSet
で使用しようとするとどうなりますか。 :
db.players.update(
{ _id: 3 },
{
$addToSet: {
scores: {
$each: [ 12 ],
$position: 0,
$sort: 1,
$slice: 5
}
}
}
)
出力:
WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 2, "errmsg" : "Found unexpected fields after $each in $addToSet: { $each: [ 12.0 ], $position: 0.0, $sort: 1.0, $slice: 5.0 }" } })
エラーメッセージは、 $ position
、 $ sort
、および $ sense
予期しないフィールドです(つまり、そこにあるべきではありません)。
$ push
で同じ修飾子を試してみましょう :
db.players.update(
{ _id: 3 },
{
$push: {
scores: {
$each: [ 12 ],
$position: 0,
$sort: 1,
$slice: 5
}
}
}
)
出力:
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
今回はエラーなしで動作しました。
結果を確認します:
db.players.find()
結果:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 3, 5, 5, 5, 12 ] }
値が追加されていることがわかります。 $ position:0
を指定したにもかかわらず 、 $ sort:1
も指定しました 、これは、配列を配置した後に配列がソートされたことを意味します。
$ slip:5
も指定しました 、これは配列を5つの要素に制限していました(結局のところ、配列に含まれる要素の数とまったく同じでした)。