Xem xét "thụt đầu dòng" mà tôi đang sử dụng trong danh sách, điều này thực sự có thể trông lâu hơn những gì bạn đang làm, nhưng thực sự thì không.
Đây là một ví dụ thực sự tốt khác về việc sử dụng $ bản đồ
như có sẵn cho MongoDB 2.6 và cao hơn. Vẫn còn một số cách sử dụng $ unwind
, nhưng các mảng "chưa được liên kết" thực sự chỉ có một yếu tố trong chúng. Vì vậy, hãy tha thứ cho "Highlander" của tôi
tài liệu tham khảo mà tôi không thể chống lại :)
db.users.aggregate([
// Match your document or documents
{ "$match": {
"commentUpvotes.id": 12
}},
// Get the one "up-votes" entry that matches
{ "$project": {
"posts": 1,
"comments": 1,
"commentUpVotes": {
"$setDifference": [
{
"$map": {
"input": "$commentUpvotes",
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el.id", 12 ] },
"$$el",
false
]
}
}
},
[false]
]
}
}},
// There is only one!
{ "$unwind": "$commentUpVotes" },
// Get the one comments entry that matches
{ "$project": {
"posts": 1,
"comments": {
"$setDifference": [
{
"$map": {
"input": "$comments",
"as": "el",
"in": {
"$cond": [
{
"$eq": [
{ "$substr": [ "$$el.id", 0, 4 ] },
"$commentUpVotes.commentId"
]
},
"$$el",
false
]
}
}
},
[false]
]
},
"commentUpVotes": 1
}},
// And there is only one!
{ "$unwind": "$comments" },
// Get the one post that matches
{ "$project": {
"posts": {
"$setDifference": [
{
"$map": {
"input": "$posts",
"as": "el",
"in": {
"$cond": [
{
"$eq": [
"$$el.id",
"$comments.postId"
]
},
"$$el",
false
]
}
}
},
[false]
]
},
"comments": 1,
"commentUpVotes": 1
}},
// Optionally group back to arrays. There can be only one!
{ "$group": {
"_id": "$_id",
"posts": { "$first": "$posts" },
"comments": { "$push": "$comments" },
"commentUpVotes": { "$push": "$commentUpVotes" }
}}
])
Vì vậy, kết quả cuối cùng sẽ là:
{
"_id" : ObjectId("539065d3cd0f2aac5f55778e"),
"posts" : [
{
"title" : "post1",
"id" : "123"
}
],
"comments" : [
{
"id" : 1910,
"postId" : "123",
"title" : "comment1",
"comment" : "some comment",
"user" : "user13"
}
],
"commentUpVotes" : [
{
"id" : 12,
"commentId" : "1910",
"upvotedBy" : "user91"
}
]
}
Tôi biết bạn đã yêu cầu "không có thay đổi giản đồ", nhưng không thực sự là thay đổi giản đồ để nói rằng bạn nên giữ id
của mình các giá trị ở đây thuộc loại nhất quán. Hiện tại bạn đang trộn Số nguyên và chuỗi trong quá trình này (tôi hy vọng đó chỉ là một ví dụ), đây không phải là một ý kiến hay.
Do đó, có một số "truyền giới hạn" thực sự có sẵn được sử dụng ở đây bằng cách sử dụng $ substr
, tuy nhiên giải pháp thực tế của bạn có thể khác nhau về cách thực hiện điều này. Tôi thực sự khuyên bạn nên sửa dữ liệu nếu nó thực sự cần sửa.
Dù sao đi nữa, một cách sử dụng khá thú vị cho $ bản đồ