Considerando il "rientro" che sto usando nell'elenco, questo potrebbe effettivamente sembrare più lungo di quello che stai facendo, ma in realtà non lo è.
Questo è un altro ottimo esempio di utilizzo di $map
come disponibile per MongoDB 2.6 e versioni successive. È ancora possibile utilizzare $unwind
, ma gli array "svolti" in realtà ne hanno solo uno elemento in essi. Quindi, per favore, perdona il mio "Highlander"
riferimenti a cui non ho resistito :)
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" }
}}
])
Quindi il risultato finale sarebbe:
{
"_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"
}
]
}
So che hai chiesto "nessuna modifica allo schema", ma non proprio una modifica allo schema per dire che è una buona idea mantenere il tuo id
valori qui di un tipo coerente. Attualmente stai mescolando interi e stringhe in questo processo (spero sia solo un esempio), il che non è una buona idea.
Quindi c'è un "casting limitato" che è effettivamente disponibile qui impiegato usando $substr
, tuttavia la tua soluzione effettiva può variare nel modo in cui farlo davvero. Suggerisco vivamente di correggere i dati se è davvero necessario ripararli.
In ogni caso, un utilizzo piuttosto interessante per $map