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

複数のオブジェクト配列ドキュメントのC#Mongodbデカルト積

    以下の集約パイプラインを試すことができます。

    mergeObjects に注意してください 集計演算子は3.5.6 +で使用できます 今後の3.6にロールインされる開発リリース リリース。

    db.collection.find();
    {
     "data" : [
      [
       {
        "movie" : "starwars",
        "showday" : "monday"
       },
       {
        "movie" : "batman",
        "showday" : "thursday"
       },
       {
        "movie" : "sleepless",
        "showday" : "tuesday"
       }
      ],
      [
       {
        "actor" : "angelina",
        "location" : "new york"
       },
       {
        "actor" : "jamie",
        "location" : "california"
       },
       {
        "actor" : "mcavoy",
        "location" : "arizona"
       }
      ]
     ]
    }
    

    条件式を使用した集計。

    aggregate({
     $project: {
      cp: {
       $reduce: {
        input: "$data",
        initialValue: {
         $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
        },
        in: {
         $let: {
          vars: {
           currentr: "$$this", // Current processing element
           currenta: "$$value" // Current accumulated value 
          },
          in: {
           $cond: [{ // Conditional expression to return the accumulated value as initial value for first element
            $eq: ["$$currentr", "$$currenta"]
           },
           "$$currenta",
           { // From second element onwards prepare the cartesian product
            $reduce: {
             input: {
              $map: {
               input: "$$currenta",
               as: a"a",
               in: {
                $map: {
                 input: "$$currentr",
                 as: r"r",
                 in: {
                  $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
                 }
                }
               }
              }
             },
             initialValue: [],
             in: {
             $concatArrays: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
             }
            }
           }]
          }
         }
        }
       }
      }
     }
    });
    

    Aggregation(using $setUnion

    このソリューションは、より読みやすいパイプラインを提供するために条件式を抑制するためにのみ追加されました。

    aggregate({
     $project: {
      cp: {
       $reduce: {
        input: "$data",
        initialValue: {
         $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
        },
        in: {
         $let: {
          vars: {
           currentr: "$$this", // Current processing element
           currenta: "$$value" // Current accumulated value 
          },
          in:{ 
           $reduce: {
            input: {
             $map: {
              input: "$$currenta",
              as: "a",
              in: {
               $map: {
                input: "$$currentr",
                as: "r",
                in: {
                 $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
                }
               }
              }
             }
            },
            initialValue: [],
            in: {
             $setUnion: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
            }
           }
          }
         }
        }
       }
      }
     }
    });
    

    更新

    $condが正しくないため、以下のAsya Kamskyのコメントに示されているように、上記の両方のソリューションは配列全体で値を繰り返すことはできません。 最初のソリューションと$setUnion 2番目のソリューションで。

    正しい修正は

    です。

    initialValueで始まります [ { } ]

    または

    inputを変更します input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},のような最初の要素を除外するには

    完全な集約パイプライン

    aggregate({
     $project: {
      cp: {
       $reduce: {
        input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},
        initialValue: {$arrayElemAt:["$data",0]},
        in: {
         $let: {
          vars: {
           currentr: "$$this", 
           currenta: "$$value" 
          },
          in:{ 
           $reduce: {
            input: {
             $map: {
              input: "$$currenta",
              as: "a",
              in: {
               $map: {
                input: "$$currentr",
                as: "r",
                in: {
                 $mergeObjects: ["$$a", "$$r"] 
                }
               }
              }
             }
            },
            initialValue: [],
            in: {
             $concatArrays: ["$$value", "$$this"] 
            }
           }
          }
         }
        }
       }
      }
     }
    });
    

    参照:JavaScriptの複数の配列のデカルト積




    1. Mongodbの実行に失敗しました

    2. MongoDBバックアップオプションを理解する

    3. C#のMongoDB db.runCommand()

    4. MongoDB C#ドライバー-_idをObjectIdとして保存し、文字列Idプロパティにマップする方法は?