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

エントリに一致する2つのフィールドが含まれていない場合、mongoはネストされた配列に追加します

    恐れ入りますが、単一のアトミック更新では不可能です。両方の条件を満たすいくつかの更新操作を実行する必要があります。

    更新ロジックを2つの異なる更新操作に分割します。最初の操作では、位置$ オペレーター history内の要素を識別するため 必要なアレイと $set> 既存のフィールドを更新します。この操作は、名前と組織が一致する場合にフィールドを更新するというロジックに従います。

    ここで、 findAndModify() 更新されたドキュメントを返すことができるため、この操作のメソッド。デフォルトでは、返されるドキュメントには、更新時に行われた変更は含まれていません。

    したがって、この武器を装備して、次の操作で2番目のロジックをプローブできます。つまり、「history.name」と「history.organisation」の組み合わせがアレイに存在しない場合は更新します 。この2回目の更新操作では、 $push 要素を追加する演算子。

    次の例は、上記の概念を示しています。最初は、クエリ部分とドキュメントが別々のオブジェクトとして更新されることを前提としています。

    たとえば、既存の履歴配列と一致するドキュメントがある場合、1回の更新操作が実行されますが、ドキュメントが一致しない場合は、 findAndModify() メソッドはnullを返します。2番目の更新操作でこのロジックを使用して、ドキュメントを配列にプッシュします。

    var doc = {
            "name": "Test123",
            "organisation": "Rat"
        }, // document to update. Note: the doc here matches the existing array
        query = { "email": "[email protected]" }; // query document
    
    query["history.name"] = doc.name; // create the update query
    query["history.organisation"] = doc.organisation;
    var update = db.users.findAndModify({
        "query": query,
        "update": { 
            "$set": { 
                "history.$.name": doc.name,
                "history.$.organisation": doc.organisation
            }
        }
    }); // return the document modified, if there's no matched document update = null
    
    if (!update) {
        db.users.update(
            { "email": query.email },
            { "$push": { "history": doc } }
        );
    }
    

    一致するドキュメントに対してこの操作を行った後、コレクションをクエリすると同じ

    が生成されます。
    db.users.find({ "email": "[email protected]" });
    

    出力:

    {
        "_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
        "email" : "[email protected]",
        "__v" : 0,
        "history" : [ 
            {
                "name" : "Test123",
                "organisation" : "Rat",
                "field" : 4,
                "another" : 3
            }
        ]
    }
    

    次に、一致しないドキュメントについて考えます。

    var doc = {
            "name": "foo",
            "organisation": "bar"
        }, // document to update. Note: the doc here does not matches the current array
        query = { "email": "[email protected]" }; // query document
    
    query["history.name"] = doc.name; // create the update query
    query["history.organisation"] = doc.organisation;
    var update = db.users.findAndModify({
        "query": query,
        "update": { 
            "$set": { 
                "history.$.name": doc.name,
                "history.$.organisation": doc.organisation
            }
        }
    }); // return the document modified, if there's no matched document update = null
    
    if (!update) {
        db.users.update(
            { "email": query.email },
            { "$push": { "history": doc } }
        );
    }
    

    このドキュメントのこのコレクションのクエリ

    db.users.find({ "email": "[email protected]" });
    

    降伏する

    出力:

    {
        "_id" : ObjectId("575fe85bfe98c1fba0a6e535"),
        "email" : "[email protected]",
        "__v" : 0,
        "history" : [ 
            {
                "name" : "Test123",
                "organisation" : "Rat",
                "field" : 4,
                "another" : 3
            }, 
            {
                "name" : "foo",
                "organisation" : "bar"
            }
        ]
    }
    



    1. オブジェクトは、MongoDBからのReact子データとしては無効です

    2. MongoDB $ tanh

    3. MongoDB整合性更新エッジケース

    4. OpenShiftでディスククォータを超えました