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

アップサートの位置($)での$pushが失敗する

    アップサートは、更新クエリのネストされたドキュメントでは機能しません

    単一のクエリで実行する場合は、集計クエリを使用して複雑な更新を試して、ケースを処理できます。

    入力例を取り上げて、ケースごとに例を見てみましょう。

    ケース1: 指定されている場合messages.from messagesにフィールドが存在します 配列

    var to = "111";
    var from = "222";
    var subMessage = {
      message: "test",
      date: ISODate("2021-06-29T15:57:53.975Z")
    };
    

    遊び場

    ケース2: messages.fromの場合 フィールドが配列に存在しません

    var to = "111";
    var from = "333";
    var subMessage = {
      message: "test2",
      date: ISODate("2021-06-29T15:57:53.975Z")
    };
    

    遊び場

    ケース3: ドキュメントが存在しない場合

    var to = "111";
    var from = "333";
    var subMessage = {
      message: "test2",
      date: ISODate("2021-06-29T15:57:53.975Z")
    };
    

    遊び場

    最終的なクエリは、

    • toのみをチェック クエリの条件
    • パーツを更新し、状態を確認します。
      • fromの場合 messagesにあります 次に配列:
        • $map messagesのループを繰り返す 配列を作成し、fromの場合は条件を確認します 見つかった後、現在のsubMessagesを連結します 新しい入力を持つ配列subMessage $concatArraysを使用する 、$mergeObjects 現在のオブジェクトを更新されたオブジェクトとマージするには
      • それ以外の場合は見つかりませんでした。次に、現在のmessagesに新しいメッセージオブジェクト配列を連結します。 $cocnatArraysを使用した配列
    • upsert: true 、コレクションに見つからない場合に新しいドキュメントを挿入する
    db.pendingMessages.updateOne(
      { to: to },
      [{
        $set: {
          messages: {
            $cond: [
              { $in: [from, { $ifNull: ["$messages.from", []] }] },
              {
                $map: {
                  input: "$messages",
                  in: {
                    $mergeObjects: [
                      "$$this",
                      {
                        subMessages: {
                          $cond: [
                            { $eq: ["$$this.from", from] },
                            {
                              $concatArrays: ["$$this.subMessages", [subMessage]]
                            },
                            "$$this.subMessages"
                          ]
                        }
                      }
                    ]
                  }
                }
              },
              {
                $concatArrays: [
                  { $ifNull: ["$messages", []] },
                  [
                    {
                      from: from,
                      subMessages: [subMessage]
                    }
                  ]
                ]
              }
            ]
          }
        }
      }],
      { upsert: true }
    )
    



    1. フィルタ付きのMongo日付範囲インデックス

    2. MongoDBの個別のコマンド

    3. MongodDB $は、配列から1つの要素のみをプルします

    4. MongoDBのセキュリティを向上させるための10のヒント