복붙노트

[MONGODB] MongoDB의 두 컬렉션을 병합

MONGODB

MongoDB의 두 컬렉션을 병합

나는 간단한 절차입니다 무슨 생각을 할 MongoDB의에서 맵리 듀스를 사용하려고했습니다. 이것이 내가 심지어 맵리 듀스를 사용 할 필요가있는 경우에, 올바른 방법입니다 나도 몰라. 하지만 아무것도 - 내가 생각하고 내가 가장 성공을 것이라고 생각 문서를 맞추려고 어떤 키워드를 봤. 어쩌면 내가 이것에 대해 너무 열심히 생각하고 있어요?

자세한 내용 및 GPA들 : 저는 두 컬렉션을

세부 사항은 문서 (3+ 만 달러)의 전체 무리 구성되어 있습니다. studentid 요소는 다음과 같이 두 번, 매년 하나를 반복 할 수 있습니다 :

{ "_id" : ObjectId("4d49b7yah5b6d8372v640100"), "classes" : [1,17,19,21], "studentid" : "12345a", "year" : 1}
{ "_id" : ObjectId("4d76b7oij7s2d8372v640100"), "classes" : [2,12,19,22], "studentid" : "98765a", "year" : 1}
{ "_id" : ObjectId("4d49b7oij7s2d8372v640100"), "classes" : [32,91,101,217], "studentid" : "12345a", "year" : 2}
{ "_id" : ObjectId("4d76b7rty7s2d8372v640100"), "classes" : [1,11,18,22], "studentid" : "24680a", "year" : 1}
{ "_id" : ObjectId("4d49b7oij7s2d8856v640100"), "classes" : [32,99,110,215], "studentid" : "98765a", "year" : 2}
...

GPA들 같은 studentid의 세부 사항에서와 요소가 있습니다. 이 같은 studentid 당 하나 개의 항목 :

{ "_id" : ObjectId("4d49b7yah5b6d8372v640111"), "studentid" : "12345a", "overall" : 97, "subscore": 1}
{ "_id" : ObjectId("4f76b7oij7s2d8372v640213"), "studentid" : "98765a", "overall" : 85, "subscore": 5}
{ "_id" : ObjectId("4j49b7oij7s2d8372v640871"), "studentid" : "24680a", "overall" : 76, "subscore": 2}
...

결국 나는이 형식으로 각 학생에 대한 하나의 행으로 컬렉션을 갖고 싶어 :

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

내가이 일을가는 방법은 다음과 맵리 듀스를 실행했다 :

var mapDetails = function() {
    emit(this.studentid, {studentid: this.studentid, classes: this.classes, year: this.year, overall: 0, subscore: 0});
};

var mapGpas = function() {
    emit(this.studentid, {studentid: this.studentid, classes: [], year: 0, overall: this.overall, subscore: this.subscore});
};

var reduce = function(key, values) {
    var outs = { studentid: "0", classes_1: [], classes_2: [], overall: 0, subscore: 0};

    values.forEach(function(value) {
        if (value.year == 0) {
            outs.overall = value.overall;
            outs.subscore = value.subscore;
        }
        else {
            if (value.year == 1) {
                outs.classes_1 = value.classes;
            }
            if (value.year == 2) {
                outs.classes_2 = value.classes;
            }

            outs.studentid = value.studentid;
        }
    });

    return outs;

};

res = db.details.mapReduce(mapDetails, reduce, {out: {reduce: 'joined'}})
res = db.gpas.mapReduce(mapGpas, reduce, {out: {reduce: 'joined'}})

내가 그것을 실행할 때,이 내 결과 모음입니다 :

{ "_id" : "12345a", "value" : { "studentid" : "12345a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 97, "subscore" : 1 } }
{ "_id" : "98765a", "value" : { "studentid" : "98765a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 85, "subscore" : 5 } }
{ "_id" : "24680a", "value" : { "studentid" : "24680a", "classes_1" : [ ], "classes_2" : [ ], "overall" : 76, "subscore" : 2 } }

나는 클래스 배열을 누락.

또한, 옆으로, 어떻게 MapReduce의 값 요소를 생성 요소에 액세스 하는가? 합니까 맵리 듀스는 항상 값 또는 어떤 다른 출력 당신은 그것을 이름?

해결법

  1. ==============================

    1.이것은 MongoDB를 사용자 Google 그룹에 질문을 받았다 질문과 유사하다. https://groups.google.com/group/mongodb-user/browse_thread/thread/60a8b683e2626ada?pli=1

    이것은 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의에서 맵리 듀스에 대한 자세한 내용은 설명서를 참조하십시오 : http://www.mongodb.org/display/DOCS/MapReduce

    또한, 맵리 듀스 작업이라는 제목의 MongoDB의 요리 책 문서의 "엑스트라"섹션에서 작동하는 방법의 유용한 단계별 연습이있다 "버전 화와 함께 문서를 찾기 최대 및 최소 값" http://cookbook.mongodb.org/patterns/finding_max_and_min/

    이미 언급 된 일부 문서를 읽을 경우 용서. 이 게시물을 읽을 수있는 다른 사용자의 이익을 위해 그들을 포함하여 MongoDB에서 맵리 듀스를 사용하여 새로운 한

    이지도 기능의 '발광'문에서 출력은 감소 기능의 출력과 일치하는 것이 중요합니다. 지도 기능에 의해 하나의 문서 출력이있는 경우, 감소 기능은 전혀 실행되지 않을 수 있습니다, 다음 출력 컬렉션 일치하지 않는 문서를해야합니다.

    나는 약간 두 개의 별도의 "클래스"배열, 원하는 출력의 형식으로 문서를 방출하는지도 문을 수정했습니다. 또한 이미 존재하지 않는 경우에만의 classes_1 및 classes_2 배열에 새로운 클래스를 추가하여 감소 문을 재 작업했다.

    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'}})
    

    원하는 형식과 일치 다음 모음에있는 두 개의 맵리 듀스 작업 결과를 실행 :

    > 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 } }
    >
    

    맵리 듀스는 항상 {: "ID", 값 : "값"_id}의 형태로 문서를 출력 "도트 표기법은 (객체에 도달)"라는 제목의 문서의 하위 문서 작업을 볼 수 있습니다 자세한 내용이 있습니다 : http://www.mongodb.org/display/DOCS/Dot+Notation+%28Reaching+into+Objects%29

    당신은 맵리 듀스의 출력이 다른 형식으로 표시 할 경우에, 당신은 당신의 응용 프로그램에서 프로그래밍 방식으로 그렇게해야합니다.

    희망이 맵리 듀스에 대한 이해를 향상시킬 것, 그리고 한 걸음 더 가까이 원하는 출력 수집을 생산하는 당신을 얻을. 행운을 빕니다!

  2. ==============================

    2.그는 하나 개의 컬렉션에 적용하도록 설계되어 있기 때문에이에 대한 m / R을 사용할 수 없습니다. 하나 개 이상의 컬렉션 읽기 호환성을 샤딩 깰 것 때문에 허용되지 않습니다. 당신은 당신이 새로운 통합 프레임 워크 (2.1) 중 하나와 함께하고 싶은 일을하거나 응용 프로그램 내에서이 작업을 수행 할 수 있습니다.

    그는 하나 개의 컬렉션에 적용하도록 설계되어 있기 때문에이에 대한 m / R을 사용할 수 없습니다. 하나 개 이상의 컬렉션 읽기 호환성을 샤딩 깰 것 때문에 허용되지 않습니다. 당신은 당신이 새로운 통합 프레임 워크 (2.1) 중 하나와 함께하고 싶은 일을하거나 응용 프로그램 내에서이 작업을 수행 할 수 있습니다.

  3. from https://stackoverflow.com/questions/9696940/merging-two-collections-in-mongodb by cc-by-sa and MIT license