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

MongoDBで2つのコレクションをマージする

    これは、MongoDBユーザーのGoogleグループで尋ねられた質問に似ています。
    https://groups.google.com/group/mongodb-user/browse_thread/thread/60a8b683e2626ada?pli=1

    答えは、あなたの例に似たオンラインチュートリアルを参照しています:http://tebros.com/2011/07/using-mongodb-mapreduce-to-join-2-collections/

    MongoDBのMapReduceの詳細については、ドキュメントを参照してください:http://www.mongodb.org/display/DOCS/MapReduce

    さらに、「バージョン管理されたドキュメントでの最大値と最小値の検索」というタイトルのMongoDBクックブックの記事の「Extras」セクションに、MapReduce操作がどのように機能するかについての便利なステップバイステップのウォークスルーがあります:http://cookbook.mongodb。 org / pattern / finding_max_and_min /

    参照されているドキュメントのいくつかをすでに読んでいる場合は、ご容赦ください。この投稿を読んでいて、MongoDBでMapReduceを使用するのが初めてのユーザーのために、これらを含めました。

    Map関数の「emit」ステートメントからの出力がReduce関数の出力と一致することが重要です。 Map関数によって出力されるドキュメントが1つしかない場合、Reduce関数がまったく実行されない可能性があり、その場合、出力コレクションには不一致のドキュメントが含まれます。

    2つの別々の「クラス」配列を使用して、希望する出力の形式でドキュメントを出力するようにmapステートメントを少し変更しました。
    また、次の場合にのみ、classes_1およびclasses_2配列に新しいクラスを追加するようにreduceステートメントを作り直しました。それらはまだ存在していません。

    var mapDetails = function(){
        var output = {studentid: this.studentid, classes_1: [], classes_2: [], year: this.year, overall: 0, subscore: 0}
        if (this.year == 1) {
            output.classes_1 = this.classes;
        }
        if (this.year == 2) {
            output.classes_2 = this.classes;
        }
        emit(this.studentid, output);
    };
    
    var mapGpas = function() {
        emit(this.studentid, {studentid: this.studentid, classes_1: [], classes_2: [], year: 0, overall: this.overall, subscore: this.subscore});
    };
    
    var r = function(key, values) {
        var outs = { studentid: "0", classes_1: [], classes_2: [], overall: 0, subscore: 0};
    
        values.forEach(function(v){
            outs.studentid = v.studentid;
            v.classes_1.forEach(function(class){if(outs.classes_1.indexOf(class)==-1){outs.classes_1.push(class)}})
            v.classes_2.forEach(function(class){if(outs.classes_2.indexOf(class)==-1){outs.classes_2.push(class)}})
    
            if (v.year == 0) {
                outs.overall = v.overall;
                outs.subscore = v.subscore;
            }
        });
        return outs;
    };
    
    res = db.details.mapReduce(mapDetails, r, {out: {reduce: 'joined'}})
    res = db.gpas.mapReduce(mapGpas, r, {out: {reduce: 'joined'}})
    

    2つのMapReduce操作を実行すると、目的の形式に一致する次のコレクションが生成されます。

    > db.joined.find()
    { "_id" : "12345a", "value" : { "studentid" : "12345a", "classes_1" : [ 1, 17, 19, 21 ], "classes_2" : [ 32, 91, 101, 217 ], "overall" : 97, "subscore" : 1 } }
    { "_id" : "24680a", "value" : { "studentid" : "24680a", "classes_1" : [ 1, 11, 18, 22 ], "classes_2" : [ ], "overall" : 76, "subscore" : 2 } }
    { "_id" : "98765a", "value" : { "studentid" : "98765a", "classes_1" : [ 2, 12, 19, 22 ], "classes_2" : [ 32, 99, 110, 215 ], "overall" : 85, "subscore" : 5 } }
    >
    

    MapReduceは、常に{_id: "id"、value: "value"}の形式でドキュメントを出力します。「DotNotation(Reaching into Objects)」というタイトルのドキュメントには、サブドキュメントの操作に関する詳細情報があります:http:/ /www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

    MapReduceの出力を別の形式で表示したい場合は、アプリケーションでプログラムで行う必要があります。

    これにより、MapReduceの理解が深まり、目的の出力コレクションの作成に一歩近づくことができれば幸いです。幸運を祈ります!



    1. springboot2.0で@cacheableを使用するときにredisキャッシュごとに異なるttlを構成する方法

    2. Moongooseの集計$matchがIDと一致しません

    3. ネイティブMongoDBマスキング(3番目の方法)

    4. 配列内のObjectIdの$lookup