Reputation: 429
I am using MongoDb 3.2.8. Below is my test collection containing 2 documents which stores balance information for a bank account. Two balances (closing and available balance are stored against 2 currencies GBP and EUR against each account.
/* 1 */
{
"_id" : "100001-AT611904300234101001",
"agref" : "100001",
"acref" : "AT611904300234101001",
"bal" : [
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "5727.8275199999998221755959093570709228515625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "5727.8275199999998221755959093570709228515625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
]
}
/* 2 */
{
"_id" : "100001-AT522904300234201001",
"agref" : "100001",
"acref" : "AT522904300234201001",
"bal" : [
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "64433.471462276895181275904178619384765625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "64433.471462276895181275904178619384765625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
]
}
What I want to do is sort test collection on balance type "CLBD" and Currency "EUR".
I have tried following:
db.test.aggregate([
{$unwind: "$bal"}
,{$match: {"bal.amt.ccy": "EUR", "bal.tp.cdOrPrtry.cd":"CLBD"}}
,{$sort: {"bal.amt.value":-1}}
]);
The output is fine to some extent i.e. it sorts the data but it removes certain fields from original document i.e. Balances in GBP, CLAV balances etc:
/* 1 */
{
"_id" : "100001-AT522904300234201001",
"agref" : "100001",
"acref" : "AT522904300234201001",
"bal" : {
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
}
/* 2 */
{
"_id" : "100001-AT611904300234101001",
"agref" : "100001",
"acref" : "AT611904300234101001",
"bal" : {
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
}
Please advice.
Upvotes: 0
Views: 48
Reputation: 37108
You can use $$ROOT
reference to the original document, but it will slightly change structure of the result:
db.test.aggregate([
{
$project: {
bal: { $filter: {
input: "$bal",
as: "bal",
cond: { $and: [
{ $eq: [ "$$bal.amt.ccy", "EUR" ] },
{ $eq: [ "$$bal.tp.cdOrPrtry.cd", "CLBD" ] }
] }
} },
doc: "$$ROOT"
}
},
{
$unwind: "$bal"
},
{
$sort: { "bal.amt.value": -1 }
}
]);
will result with an ordered list of elements, including doc
field, which contains the whole document:
/* 1 */
{
"_id" : "100001-AT522904300234201001",
"bal" : {
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
"doc" : {
"_id" : "100001-AT522904300234201001",
"agref" : "100001",
"acref" : "AT522904300234201001",
"bal" : [
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "72579.83178142391261644661426544189453125",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "64433.471462276895181275904178619384765625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "64433.471462276895181275904178619384765625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
]
}
}
/* 2 */
{
"_id" : "100001-AT611904300234101001",
"bal" : {
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
"doc" : {
"_id" : "100001-AT611904300234101001",
"agref" : "100001",
"acref" : "AT611904300234101001",
"bal" : [
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "6452",
"ccy" : "EUR"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLAV"
}
},
"amt" : {
"value" : "5727.8275199999998221755959093570709228515625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
},
{
"tp" : {
"cdOrPrtry" : {
"cd" : "CLBD"
}
},
"amt" : {
"value" : "5727.8275199999998221755959093570709228515625",
"ccy" : "GBP"
},
"cdtDbtInd" : "CRDT",
"dt" : {
"dt" : "2016-06-30"
}
}
]
}
}
Upvotes: 1