programing

MongoDB에서 하위 문서를 루트 수준으로 평평하게 만드는 방법은 무엇입니까?

instargram 2023. 6. 11. 10:17
반응형

MongoDB에서 하위 문서를 루트 수준으로 평평하게 만드는 방법은 무엇입니까?

예를 들어, 내가 이런 문서를 가지고 있다면,

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

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

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

MongoDB 투영, 즉 집계 프레임워크 파이프라인 연산자도 사용할 수 있습니다.(권장 방법).사용하지 않으려는 경우project 링크를 확인합니다.

db.collection.configuration([{$project{ . . }}]);

다음은 귀사의 사례입니다.

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

예상한 대로 출력을 제공합니다.

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

다음과 같이 스테이지와 함께 사용할 수 있습니다.

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

및 연산자의 별칭을 사용하여 이 작업을 수행할 수 있습니다.

let pipeline = [
   {
      "$replaceWith": {
         "$mergeObjects": [ { "a": "$a" }, "$subdoc" ]
      }
   }
];

또는

let pipeline = [
    {
        "$replaceRoot": {
            "newRoot": {
                "$mergeObjects": [{ "a": "$a" }, "$subdoc" ]
            }
        }
    }
];

db.collection.aggregate(pipeline)

사용할 수도 있습니다.$$ROOT$mergeObjects

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

시작하는Mongo 4.2집계 연산자를 사용하여 문서를 다른 문서(우리의 경우 하위 문서)로 대체할 수 있습니다.$replaceRoot@hablidam이 언급했습니다.

따라서 우리는 먼저 연산자를 계속 사용하기 위한 루트 필드를 하위 문서에 포함할 수 있습니다(또한 에서 소개됨).Mongo 4.2의 가명으로$addFields)를 사용하여 전체 문서를 하위 문서로 바꿉니다.$replaceWith:

// { a: 1, subdoc: { b: 2, c: 3 } }
db.collection.aggregate([
  { $set: { "subdoc.a": "$a" } },
  { $replaceWith: "$subdoc" }
])
// { b: 2, c: 3, a: 1 }

중첩 배열 요소를 쿼리하여 루트 수준에서 표시하려면 중첩 배열이 2개인 경우 $unwind를 두 번 사용해야 합니다.

db.mortgageRequests.aggregate( [
       { $unwind: "$arrayLevel1s" },
       { $unwind: "$arrayLevel1s.arrayLevel2s" },
       { $match: { "arrayLevel1s.arrayLevel2s.documentid" : { $eq: "6034bceead4ed2ce3951f38e" } } },
       { $replaceRoot: { newRoot: "$arrayLevel1s.arrayLevel2s" } }
    ] )

제 생각에 가장 쉬운 방법은 결과가 돌아온 후에 변경하는 것 같습니다.map.

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);

를 사용하여 이 작업을 수행할 수 있습니다.

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" }
    );
})

또한 "하위 문서" 키가 실제로 있는 문서를 선택하기 위해 의 안전한 사용을 사용합니다.

언급URL : https://stackoverflow.com/questions/22903849/how-to-flatten-a-subdocument-into-root-level-in-mongodb

반응형