sql >> データベース >  >> NoSQL >> MongoDB

MongoDB $pushと$addToSet:違いは何ですか?

    MongoDBには$pushがあります 演算子と$addToSet 演算子、どちらも非常によく似た処理を行います。

    どちらの演算子も、既存の配列に値を追加します。主な違いは、追加しようとしている値がすでに含まれている配列を処理する方法と、使用できる修飾子にあります。

    違い

    既存の値 値が配列にすでに存在する場合は、 $ push 引き続き値を追加します(結果として値が重複します)。
    ただし、 $ addToSet 値がまだ配列に存在しない場合にのみ値を追加します。したがって、値がすでに存在する場合は、 $ addToSet 追加しません(何もしません)。
    修飾子 $ push 演算子は、 $ sortなどの追加の修飾子とともに使用できます。 、$スライス 、および $ position 、一方、 $ addToSet できません(少なくとも、MongoDB 4.4以降ではありません)。

    既存の値

    次のドキュメントを含むコレクションがあるとします。

    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つの要素に制限していました(結局のところ、配列に含まれる要素の数とまったく同じでした)。


    1. mongodbからのtransparent_hugepage/defrag警告を回避する方法は?

    2. RailsにMongoidを搭載したMongoDB-地理空間インデックス

    3. MongoCredentialおよび未分類のMongoDb例外の認証の例外

    4. Redisクラスター/負荷分散