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

マングースは配列を更新するか、配列に追加します

    主な問題は、findOneAndUpdate その名前が意味することを正確に行います。 findを実行します 提供されたフィルターを使用し、一致するものが見つかった場合は、最初に一致したドキュメントに更新を適用します。

    コレクションにこのドキュメントのみが含まれている場合:

    [
        {
            "_id": "5e90ae0e0ed9974174e92826",
            "payments": [
                {
                    "year_month": "2020_02",
                    "status": false
                }
            ]
        }
    ]
    

    最初の検索部分は基本的に

    です
    .find({
            _id: '5e90ae0e0ed9974174e92826',
            payments: { $elemMatch: { year_month: '2020_03' }}
    })
    

    これは何にも一致しません。upsertがtrueに設定されているため、fineOneAndUpdateは新しいドキュメントを作成しようとします。一致しない位置演算子から配列を作成できたとしても、追加しようとしているドキュメントは次のようになります。

     {
            "_id": "5e90ae0e0ed9974174e92826",
            "payments": [
                {
                    "year_month": "2020_03",
                    "status": false
                }
            ]
    }
    

    これは正しくなく、_idが重複しているため挿入に失敗します とにかく価値があります。

    MongoDB 4.2を使用している場合は、findAndUpdateの2番目の引数として集計パイプラインを使用できます。 目的の要素の配列を確認し、欠落している場合は追加します。

    あまりきれいではない方法の1つを以下に示します。 findOneAndUpdateは_idと一致し、パイプラインは次のようになります。
    -配列内のいずれかの要素が目的のyear_monthと一致するかどうかを確認します
    -一致する場合は、配列を$ reduceして、その要素のステータスフィールドを更新します
    -そうでない場合は、新しい要素を追加します
    -結果をpaymentsに割り当てます

    .findOneAndUpdate(
        { "_id": "5e90ae0e0ed9974174e92826" },
        [{$set: {
             payments: {$cond:[
                     {$gt:[
                           {$size:
                                 {$filter:{
                                      input:"$payments", 
                                      cond:{$eq:["$$this.year_month","2020_03"]}
                           }}},
                           1
                      ]},
                      {$reduce:{
                            input:"$payments",
                            initialValue:[],
                            in:{$concatArrays:[
                                      "$$value",
                                      [{$cond:[
                                           {$eq:["$$this.j",3]},
                                           {$mergeObjects:["$$this",{status:true}]},
                                           "$$this"
                                      ]}]
                            ]}
                      }},
                      {$concatArrays:[
                           "$payments",
                           [{year_month:"2020_03", status:true}]
                      ]}
              ]}
         }}]
    )
    


    1. Node.jsMongodb-ネイティブドライバー接続の共有

    2. MongoDBとJavascriptを使用して、プロジェクションのサブドキュメントプロパティをカウントします

    3. Node.jsのcastArrayFiltersで未定義のプロパティ'castForQuery'を読み取ることができません

    4. MongoDBネストされたグループ?