3레벨의 MongoDB 중첩 조회
데이터베이스에서 단일 개체 계층 전체를 JSON으로 가져와야 합니다.실제로, 이 결과를 달성하기 위한 다른 솔루션에 대한 제안은 매우 감사할 것입니다.MongoDB를 MongoDB와 함께 사용하기로 했습니다.$lookup
지지하다.
세 가지 컬렉션이 있습니다.
파티
{ "_id" : "2", "name" : "party2" }
{ "_id" : "5", "name" : "party5" }
{ "_id" : "4", "name" : "party4" }
{ "_id" : "1", "name" : "party1" }
{ "_id" : "3", "name" : "party3" }
주소.
{ "_id" : "a3", "street" : "Address3", "party_id" : "2" }
{ "_id" : "a6", "street" : "Address6", "party_id" : "5" }
{ "_id" : "a1", "street" : "Address1", "party_id" : "1" }
{ "_id" : "a5", "street" : "Address5", "party_id" : "5" }
{ "_id" : "a2", "street" : "Address2", "party_id" : "1" }
{ "_id" : "a4", "street" : "Address4", "party_id" : "3" }
어드레스 코멘트
{ "_id" : "ac2", "address_id" : "a1", "comment" : "Comment2" }
{ "_id" : "ac1", "address_id" : "a1", "comment" : "Comment1" }
{ "_id" : "ac5", "address_id" : "a5", "comment" : "Comment6" }
{ "_id" : "ac4", "address_id" : "a3", "comment" : "Comment4" }
{ "_id" : "ac3", "address_id" : "a2", "comment" : "Comment3" }
모든 상대방이 대응하는 주소를 가지고 있는 것을 모두 취득해, 기록의 일부로서 코멘트를 수신할 필요가 있습니다.나의 집약:
db.party.aggregate([{
$lookup: {
from: "address",
localField: "_id",
foreignField: "party_id",
as: "address"
}
},
{
$unwind: "$address"
},
{
$lookup: {
from: "addressComment",
localField: "address._id",
foreignField: "address_id",
as: "address.addressComment"
}
}])
결과가 좀 이상해요.몇 가지 기록은 괜찮습니다.하지만 파티는_id: 4
가 없습니다(주소는 없습니다).또, 2개의 파티가 있습니다._id: 1
(다만, 주소가 다른 경우):
{
"_id": "1",
"name": "party1",
"address": {
"_id": "2",
"street": "Address2",
"party_id": "1",
"addressComment": [{
"_id": "3",
"address_id": "2",
"comment": "Comment3"
}]
}
}{
"_id": "1",
"name": "party1",
"address": {
"_id": "1",
"street": "Address1",
"party_id": "1",
"addressComment": [{
"_id": "1",
"address_id": "1",
"comment": "Comment1"
},
{
"_id": "2",
"address_id": "1",
"comment": "Comment2"
}]
}
}{
"_id": "3",
"name": "party3",
"address": {
"_id": "4",
"street": "Address4",
"party_id": "3",
"addressComment": []
}
}{
"_id": "5",
"name": "party5",
"address": {
"_id": "5",
"street": "Address5",
"party_id": "5",
"addressComment": [{
"_id": "5",
"address_id": "5",
"comment": "Comment5"
}]
}
}{
"_id": "2",
"name": "party2",
"address": {
"_id": "3",
"street": "Address3",
"party_id": "2",
"addressComment": [{
"_id": "4",
"address_id": "3",
"comment": "Comment4"
}]
}
}
이것 좀 도와주세요.저는 MongoDB에 익숙하지 않지만 MongoDB는 제가 원하는 것을 할 수 있다고 생각합니다.
'문제'의 원인은 두 번째 집약 단계입니다.{ $unwind: "$address" }
.이것에 의해, 와의 파티의 레코드가 삭제됩니다._id: 4
(주소 배열이 비어있기 때문에) 통화 상대용으로 2개의 레코드를 생성합니다._id: 1
그리고._id: 5
(각각 2개의 주소가 있기 때문입니다).
주소가 없는 통화자의 삭제를 방지하려면
preserveNullAndEmptyArrays
하기 위한 스테이지 옵션true
.다른 주소에 대한 파티의 복제를 방지하려면 파이프라인에 집계 단계를 추가해야 합니다.또한 연산자와 함께 스테이지를 사용하여 출력에서 빈 주소 레코드를 제외합니다.
db.party.aggregate([{
$lookup: {
from: "address",
localField: "_id",
foreignField: "party_id",
as: "address"
}
}, {
$unwind: {
path: "$address",
preserveNullAndEmptyArrays: true
}
}, {
$lookup: {
from: "addressComment",
localField: "address._id",
foreignField: "address_id",
as: "address.addressComment",
}
}, {
$group: {
_id : "$_id",
name: { $first: "$name" },
address: { $push: "$address" }
}
}, {
$project: {
_id: 1,
name: 1,
address: {
$filter: { input: "$address", as: "a", cond: { $ifNull: ["$$a._id", false] } }
}
}
}]);
mongodb 3.6 이상의 구문에서는 를 사용하지 않고 네스트필드를 결합하는 것은 매우 간단합니다.
db.party.aggregate([
{ "$lookup": {
"from": "address",
"let": { "partyId": "$_id" },
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$party_id", "$$partyId"] }}},
{ "$lookup": {
"from": "addressComment",
"let": { "addressId": "$_id" },
"pipeline": [
{ "$match": { "$expr": { "$eq": ["$address_id", "$$addressId"] }}}
],
"as": "address"
}}
],
"as": "address"
}},
{ "$unwind": "$address" }
])
언급URL : https://stackoverflow.com/questions/36019713/mongodb-nested-lookup-with-3-levels
'programing' 카테고리의 다른 글
mongo에 인증할 수 없습니다. "auth failures" (0) | 2023.03.05 |
---|---|
워드프레스가 내 URL 끝에 %E2%80%8E을(를) 넣는데, 어떻게 된 거죠? (0) | 2023.03.05 |
Oracle 데이터베이스에 존재하는 모든 역할을 나열하는 방법은 무엇입니까? (0) | 2023.03.05 |
흐름(원어민 반응)에서 'this.state' 사용에 대한 오류가 표시됨 (0) | 2023.03.05 |
워드프레스 에이잭스 요청 핸들러에서 쿠키를 설정하려면 어떻게 해야 합니까? (0) | 2023.03.05 |