Biorąc pod uwagę „wcięcie”, którego używam we wpisie, może to w rzeczywistości wyglądać dłużej niż to, co robisz, ale tak naprawdę nie jest.
To kolejny naprawdę dobry przykład użycia $ mapa
jako dostępny dla MongoDB 2.6 i nowszych. Nadal istnieje pewne zastosowanie $unwind
, ale tablice „odwijane” w rzeczywistości mają tylko jeden element w nich. Więc proszę wybacz mojemu "Góralowi"
referencje, którym nie mogłem się oprzeć :)
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" }
}}
])
Wynik końcowy byłby więc następujący:
{
"_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"
}
]
}
Wiem, że prosiłeś o „brak zmian w schemacie”, ale tak naprawdę nie o zmianę schematu, aby powiedzieć, że dobrym pomysłem jest zachowanie id
wartości tutaj spójnego typu. Obecnie mieszasz w tym procesie liczby całkowite i łańcuchy (mam nadzieję, że to tylko przykład), co nie jest dobrym pomysłem.
W związku z tym istnieje pewne "ograniczone przesyłanie", które faktycznie jest dostępne tutaj przy użyciu $substr
, jednak rzeczywiste rozwiązanie może się różnić w zależności od tego, jak to zrobić. Zdecydowanie sugeruję naprawienie danych, jeśli naprawdę wymagają naprawy.
W każdym razie całkiem fajne użycie dla $ mapa