연결된 개체가있는 MongoDB 집계 파이프 라인

Nov 21 2020

하나의 쿼리에서 두 개체를 연결하고 집계 함수를 사용합니다. 일부 데이터는 현지화되어 있으며 여기 에서 솔루션을 사용하여 지정된 로캘에 대한 데이터를 가져옵니다.

연결된 개체 (방)의 데이터로 동일한 작업을 수행하는 데 어려움을 겪고 있습니다. 특히 roomDetails에서 지정된 로케일에 대한 데이터를 나열합니다.

몽고 놀이터를 살펴보세요

답변

2 turivishal Nov 21 2020 at 14:09

$addFields필터링하는 두 번째 단계 에 필터를 추가하기 만하면 roomTypes나머지 단계는 동일합니다. 아래의 새 코드를 시작 주석과 끝 주석에서 강조 표시하기 만하면됩니다.

구현 된 쿼리에서이 솔루션을 제안하고 있습니다. 이것이 올바른 접근 방식인지 확실하지 않습니다. 쿼리 성능이 더 높아질 수 있습니다.

  • $reduceroomDetails.description배열 $ cond의 루프를 반복 하여 로컬과 일치하고 일치 결과를 값에 반환하고 roomDetails.title배열에 대해 동일한 프로세스를 사용 하고이 2 개의 업데이트 된 필드를 현재 객체와 병합합니다.$mergeObjects
  {
    $addFields: { roomTypes: { $map: {
          input: "$roomTypes", in: { $mergeObjects: [
              "$$this",
              {

스타트:

                roomDetails: {
                  $mergeObjects: [
                    "$$this.roomDetails", { description: { $reduce: {
                          input: "$$this.roomDetails.description", initialValue: "", in: { $cond: [
                              { $eq: ["$$this.locale", "pl"] },
                              "$$this.value", "$$value"
                            ]
                          }
                        }
                      },
                      title: {
                        $reduce: { input: "$$this.roomDetails.title",
                          initialValue: "",
                          in: {
                            $cond: [ { $eq: ["$$this.locale", "pl"] }, "$$this.value",
                              "$$value"
                            ]
                          }
                        }
                      }
                    }
                  ]
                },

~ 끝 ~

                available: {
                  $reduce: {
                    input: "$$this.capacity", initialValue: 0, in: { $cond: [
                        { $eq: ["$$this.cruiseID", "$cruiseID"] }, "$$this.available",
                        "$$value"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }

운동장


일반 옵션에서 참조 질문에 대답했습니다. 같은 기능을 사용할 수 있습니다.

function languageFilter(inputField, locale) {
  return {
    $reduce: {
      input: inputField,
      initialValue: "",
      in: {
        $cond: [{ $eq: ["$$this.locale", locale] }, "$$this.value", "$$value"]
      }
    }
  };
}

최종 쿼리는 다음과 같습니다.

let locale = "pl";
db.cs.aggregate([
  { $match: { cID: "00001" } },
  {
    $lookup: { from: "rooms", localField: "roomTypes.roomID", foreignField: "roomID", as: "roomTypes" } }, { $addFields: {
      title: languageFilter("$title", locale), description: languageFilter("$description", locale),
      roomTypes: {
        $map: { input: "$roomTypes",
          in: {
            $mergeObjects: [ "$$this",
              {
                roomDetails: {
                  $mergeObjects: [ "$$this.roomDetails",
                    {
                      description: languageFilter("$$this.roomDetails.description", locale), title: languageFilter("$$this.roomDetails.title", locale)
                    }
                  ]
                },
                available: {
                  $reduce: { input: "$$this.capacity",
                    initialValue: 0,
                    in: {
                      $cond: [ { $eq: ["$$this.cruiseID", "$cruiseID"] },
                        "$$this.available", "$$value"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      "roomTypes": { _id: 0 },
      "roomTypes.capacity": 0
    }
  }
]);