S ohledem na "odsazení", které ve výpisu používám, to může ve skutečnosti vypadat déle než to, co děláte, ale ve skutečnosti tomu tak není.
Toto je další opravdu dobrý příklad použití $ mapa
dostupné pro MongoDB 2.6 a vyšší. Stále existuje určité použití $unwind
, ale „odvíjená“ pole mají ve skutečnosti vždy jen jedno prvek v nich. Takže prosím odpusťte můj "Highlander"
reference, kterým jsem nemohl odolat :)
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" }
}}
])
Takže konečný výsledek by byl:
{
"_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"
}
]
}
Vím, že jste požádali o "žádné změny schématu", ale ve skutečnosti ne o změnu schématu, abyste řekli, že je dobrý nápad ponechat si id
hodnoty zde konzistentního typu. V současné době v tomto procesu mícháte celá čísla a řetězce (doufám, že je to jen příklad), což není dobrý nápad.
Existuje tedy určitý "omezený casting", který je ve skutečnosti dostupný a který je zde použit pomocí $substr
Vaše skutečné řešení se však může lišit v tom, jak to skutečně udělat. Důrazně doporučuji opravit data, pokud opravdu potřebují opravu.
V každém případě je to docela skvělé využití pro $ mapa