Tôi cần truy xuất toàn bộ phân cấp đối tượng đơn lẻ từ cơ sở dữ liệu dưới dạng JSON. Trên thực tế, đề xuất về bất kỳ giải pháp nào khác để đạt được kết quả này sẽ được đánh giá cao. Tôi quyết định sử dụng MongoDB với hỗ trợ tra cứu $.MongoDB tra cứu lồng nhau với 3 cấp độ
Vì vậy, tôi có ba bộ sưu tập:
bên
{ "_id" : "2", "name" : "party2" }
{ "_id" : "5", "name" : "party5" }
{ "_id" : "4", "name" : "party4" }
{ "_id" : "1", "name" : "party1" }
{ "_id" : "3", "name" : "party3" }
địa chỉ
{ "_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" }
addressComment
{ "_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" }
Tôi cần truy xuất tất cả các bên có tất cả các địa chỉ và nhận xét địa chỉ tương ứng như là một phần của hồ sơ. Tập hợp của tôi:
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"
}
}])
Kết quả là khá lạ. Một số bản ghi là ok. Nhưng Đảng với _id 4 bị thiếu (không có địa chỉ cho nó). Ngoài ra còn có hai bên _id 1 trong tập kết quả (nhưng có địa chỉ khác nhau):
{
"_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"
}]
}
}
Hãy giúp tôi với điều này. Tôi khá mới với MongoDB nhưng tôi cảm thấy nó có thể làm những gì tôi cần từ nó.
Tank you Shad! Có một vấn đề nhỏ với kỷ lục 4 mặc dù: '{ \t "_id": "4", \t "tên": "party4", \t "địa chỉ": [{ \t \t "addressComment": [] \t}] } ' Như bạn có thể thấy - địa chỉ phải là rỗng nhưng thay vào đó là bản ghi trống ... Chúng tôi có thể bỏ qua địa chỉ này nếu địa chỉ của nó trống không? Trong trường hợp khác, địa chỉ này sẽ được coi là một bản ghi. – Yuriy
Thực ra tôi thấy rằng giải pháp được cung cấp hoạt động như mong đợi theo mô tả của trường "preserveNullAndEmptyArrays" mới cho hoạt động $ relax (kể từ 3.2). Bây giờ chúng ta có thể bỏ qua bước "$ project" và chỉ định "$ relax" thay vì đơn giản: '$ unwind: {path:" $ address ", preserveNullAndEmptyArrays: true}'.Tôi sẽ chấp nhận câu trả lời của bạn, cảm ơn bạn đã trả lời nhanh chóng và rõ ràng! – Yuriy
@Shad Tôi có câu hỏi khá giống nhau. Ở đây mã OP chỉ có một thuộc tính được gọi là 'name' trong bộ sưu tập' party' và do đó bạn đã sử dụng '$ first' để lấy nó trong' $ group'. Giả sử tôi có 10 thuộc tính, sau đó có cách nào để tự động nhận tất cả thuộc tính mà không đề cập đến từng thuộc tính riêng lẻ không? – Xyroid