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

MongoDB-$projectネストされたドキュメントをルートレベルに

    MongoDB 3.6以降では、 $ replaceRoot $と組み合わせて適用できるパイプラインmergeObjects newRootとしての演算子 表現。

    この表現

    { "$mergeObjects": ["$subdoc", "$$ROOT"] }
    

    ドキュメントの最上位フィールドをサブドキュメント埋め込みフィールドのフィールドとマージするため、最終的に集約操作は次のようになります。

    db.collection.aggregate([
        { "$replaceRoot": { 
            "newRoot": { 
                "$mergeObjects": [ "$subdoc", "$$ROOT" ] 
            } 
        } },
        { "$project": { "subdoc": 0 } }  
    ])
    

    それ以外の場合は、動的な $ projectをアセンブルするために必要なすべての動的キーを取得するメカニズムが必要になります。 資料。これは、 Map-Reduce を介して可能です。 。次のmapreduce操作は、 _idとしてすべてのキーを別のコレクションに入力します 値:

    mr = db.runCommand({
        "mapreduce": "my_collection",
        "map" : function() {
            for (var key in this.subdoc) { emit(key, null); }
        },
        "reduce" : function(key, stuff) { return null; }, 
        "out": "my_collection" + "_keys"
    })
    

    すべての動的キーのリストを取得するには、結果のコレクションで個別に実行します。

    db[mr.result].distinct("_id")
    ["field2", "field3", ...]
    

    上記のリストがあれば、 $ projectを組み立てることができます ループ内でプロパティが設定されるオブジェクトを作成することにより、パイプラインドキュメントを集約します。通常、 $ project ドキュメントは次の構造になります:

    var project = {
        "$project": {
            "field1": 1,
            "field2": "$subdoc.field2",
            "field3": "$subdoc.field3"
        }
    };
    

    したがって、上記のサブドキュメントキーのリストを使用すると、JavaScriptの reduce() 方法:

    var subdocKeys = db[mr.result].distinct("_id"),
        obj = subdocKeys.reduce(function (o, v){
          o[v] = "$subdoc." + v;
          return o;
        }, { "field1": 1 }),
        project = { "$project": obj };
    
    db.collection.aggregate([project]);
    



    1. ノードJSRedisクライアント接続の再試行

    2. mongodbに埋め込まれたコメントページング

    3. コマンドがスクリプトで失敗し、コマンドラインで機能する

    4. MongoDBの条件付き$sum