복붙노트

[MONGODB] 어떻게하여 MongoDB의 루트 레벨로 하위 문서를 평평하게하는?

MONGODB

어떻게하여 MongoDB의 루트 레벨로 하위 문서를 평평하게하는?

예를 들어,이 같은 문서가있는 경우

{
  a: 1,
  subdoc: {
          b: 2,
          c: 3
          }
}

어떻게하면 이런 형식으로 변환 할 수 있습니까? (프로젝트를 사용하지 않고)

{
  a: 1,
  b: 2,
  c: 3
}

해결법

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

    1.당신은 $ 프로젝트 통합 프레임 워크 파이프 라인 운영자 즉 MongoDB의 투영을 사용뿐만 아니라 수 있습니다. (권장되는 방법). 사용하지 않으려면 프로젝트는이 링크를 확인

    당신은 $ 프로젝트 통합 프레임 워크 파이프 라인 운영자 즉 MongoDB의 투영을 사용뿐만 아니라 수 있습니다. (권장되는 방법). 사용하지 않으려면 프로젝트는이 링크를 확인

    아래는 경우에 대한 예입니다 :

    db.collectionName.aggregate
    ([
        { $project: { a: 1, 'b': '$subdoc.b', 'c': '$subdoc.c'} }
    ]);
    

    당신이 예상대로 출력을 제공 즉,

        {
            "a" : 1,
            "b" : 2,
            "c" : 3
        }
    
  2. ==============================

    2.다음과 같이 달러 (A $)의 addFields 단계로 $ replaceRoot을 사용할 수 있습니다 :

    다음과 같이 달러 (A $)의 addFields 단계로 $ replaceRoot을 사용할 수 있습니다 :

    db.collection.aggregate([
        { "$addFields": { "subdoc.a": "$a" } },
        { "$replaceRoot": { "newRoot": "$subdoc" }  }
    ])
    
  3. ==============================

    3.가장 좋은 방법은 $ replaceRoot와 $ mergeObjects 함께

    가장 좋은 방법은 $ replaceRoot와 $ mergeObjects 함께

    let pipeline = [
        {
            "$replaceRoot":{
                "newRoot":{
                    "$mergeObjects":[
                        {
                            "a":"$a"
                        },
                        "$subdoc"
                    ]
                }
            }
        }
    ]
    db.collection.aggregate(pipeline)
    
  4. ==============================

    4.당신은 $ 세트의 사용 및 $ 해제하여이 작업을 수행 할 수 있습니다

    당신은 $ 세트의 사용 및 $ 해제하여이 작업을 수행 할 수 있습니다

    db.collection.update({},{ $set: { "b": 2, "c": 3 }, $unset: { "subdoc": 1 } })
    

    물론 컬렉션의 문서가 많이가있는 경우에, 당신은 값을 얻기 위해 루프 컬렉션 문서를 필요로 훨씬 위에있다. MongoDB를 혼자 업데이트 작업의 필드의 값을 참조하는 방법이 있습니다 :

    db.collection.find({ "subdoc": {"$exists": 1 } }).forEach(function(doc) {
        var setDoc = {};
        for ( var k in doc.subdoc ) {
            setDoc[k] = doc.subdoc[k];
        }
        db.collection.update(
            { "_id": doc._id },
            { "$set": setDoc, "$unset": "subdoc" }
        );
    })
    

    그것도 $의 일부 안전한 사용이 "subdoc"키가 실제로있는 곳에 당신이 선택하는 문서를 만들기 위해 존재 고용하고있다.

  5. ==============================

    5.나는 그것을 반환 후 가장 쉬운 방법은지도를 사용하여, 그 결과를 변경한다 같아요.

    나는 그것을 반환 후 가장 쉬운 방법은지도를 사용하여, 그 결과를 변경한다 같아요.

    collection.mapFunction = function(el) {
      el.b = el.subdoc.b;
      el.c = el.subdoc.c
      delete(el.subdoc);
      return el;
    }
    
    ...
    
    var result = await collection.aggregate(...).toArray();
    result = result.map(collection.mapFunction);
    
  6. ==============================

    6.몽고 4.2 시작하여 $ replaceWith 집합 연산자 replaceRoot가 @chridam으로 언급 $ syntaxic위한 설탕 (하위 문서에서 우리의 경우)에 의해 다른 문서를 대체 할 수있다.

    몽고 4.2 시작하여 $ replaceWith 집합 연산자 replaceRoot가 @chridam으로 언급 $ syntaxic위한 설탕 (하위 문서에서 우리의 경우)에 의해 다른 문서를 대체 할 수있다.

    우리는 첫 번째 (또한 $ addFields에 대한 별칭으로 몽고 4.2에 도입)은 $ 집합 연산자를 계속 사용하고 $ replaceWith를 사용하여 하위 문서에서 전체 문서를 대체 할 하위 문서 내에서 루트 필드를 포함하여 수 :

    // { a: 1, subdoc: { b: 2, c: 3 } }
    db.collection.aggregate([
      { $set: { "subdoc.a": "$a" } },
      { $replaceWith: "$subdoc" }
    ])
    // { b: 2, c: 3, a: 1 }
    
  7. from https://stackoverflow.com/questions/22903849/how-to-flatten-a-subdocument-into-root-level-in-mongodb by cc-by-sa and MIT license