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

MongoDB-配列要素を更新またはプッシュするための$set

    実際にあなたがしているように見えることをすることは、単一の操作ではありませんが、これを行うために必要な部分、または他の可能な状況をカバーするために必要な部分を説明します。

    あなたが探しているのは、部分的に位置的な$です オペレーター。必要な配列の要素も「検索」するには、クエリの一部が必要です。

    db.products.update(
        { 
            "_id": ObjectId("536c55bf9c8fb24c21000095"),
            "recentviews.viewedby": "abc"
        },
        { 
            "$set": { 
                "recentviews.$.vieweddate": ISODate("2014-05-09T04:12:47.907Z")
            }
        }
    )
    

    つまり、$ 配列内の一致した位置を表すため、更新部分は配列内のどの項目を更新するかを認識します。配列内のドキュメントの個々のフィールドにアクセスすることも、ドキュメント全体を指定してその位置で更新することもできます。

    db.products.update(
        { 
            "_id": ObjectId("536c55bf9c8fb24c21000095"),
            "recentviews.viewedby": "abc"
        },
        { 
            "$set": { 
                "recentviews.$": {
                     "viewedby": "abc",
                     "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
            }
        }
    )
    

    フィールドが実際には変更されず、まったく同じものが存在しない場合に新しい配列要素を挿入したい場合は、 $addToSetを使用できます。

    db.products.update(
        { 
            "_id": ObjectId("536c55bf9c8fb24c21000095"),
            "recentviews.viewedby": "abc"
        },
        { 
            $addToSet:{ 
                "recentviews": {
                     "viewedby": "abc",
                     "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
            }
        }
    )
    

    ただし、単一のキー値が存在しない場合に配列への「プッシュ」を探しているだけの場合は、最初に配列内の要素が存在するかどうかを確認してから $push そうでない場合のステートメント。

    更新の影響を受けるドキュメントの数を追跡することで、これを行う際にマングースの方法からいくつかの助けを得ることができます:

    Product.update(
        { 
            "_id": ObjectId("536c55bf9c8fb24c21000095"),
            "recentviews.viewedby": "abc"
        },
        { 
            "$set": { 
                "recentviews.$": {
                     "viewedby": "abc",
                     "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
            }
        },
        function(err,numAffected) {
    
            if (numAffected == 0) {
                // Document not updated so you can push onto the array
                Product.update(
                    { 
                        "_id": ObjectId("536c55bf9c8fb24c21000095")
                    },
                    { 
                        "$push": { 
                            "recentviews": {
                                "viewedby": "abc",
                                "vieweddate": ISODate("2014-05-09T04:12:47.907Z")
                            }
                        }
                    },
                    function(err,numAffected) {
    
                    }
                );
            }            
    
        }
    );
    

    ここでの唯一の注意点は、MongoDB2.6から以前のバージョンへのwriteConcernメッセージの実装が少し変更されていることです。マングースAPIが実際にnumAffectedの戻り値をどのように実装するかについて現時点では不明です。 コールバックの引数は、違いが何かを意味する可能性があります。

    以前のバージョンでは、最初の更新で送信したデータが既存の要素と完全に一致し、実際の変更が必要なかった場合でも、「変更された」量は1として返されます。 実際には何も更新されていませんが。

    MongoDB 2.6以降、書き込み懸念応答には2つの部分が含まれています。 1つの部分は変更されたドキュメントを示し、もう1つの部分は一致を示します。したがって、既存の要素に一致するクエリ部分によって一致が返されますが、実際に変更されたドキュメント数は0として返されます。 実際に変更が必要ない場合。

    したがって、戻り値が実際にマングースでどのように実装されているかによっては、 $addToSetを使用する方が実際には安全な場合があります。 その内部更新の演算子を使用して、影響を受けるドキュメントがゼロの理由が、正確な要素がすでに存在しているだけではないことを確認します。




    1. マングース応答のオブジェクトプロパティにアクセスできません

    2. セロリ労働者が一生懸命死んだ場合、仕事は再試行されますか?

    3. Mongooseで既存のコレクションにアクセスするにはどうすればよいですか?

    4. 文字列をMongoDBのサブ文字列または文字の配列に分割します