Reputation: 9734
Given the following document...
{ "_id": ObjectId("56116d8e4a0000c9006b57ac"), "name": "Stock 1", "items" [
{ "price": 1.50, "desc": "Item 1" }
{ "price": 1.70, "desc": "Item 2" }
{ "price": 1.10, "desc": "Item 3" }
]
}
I want to get the item with the lowest price. Here below is my attempt to sort prices from lowest to highest:
db.stock.wip.aggregate([
{$unwind: "$items"},
{$sort: {"items.price":1}},
{$group: {_id:"$_id", items: {$push:"$items"}}}
]);
... and here is the result:
"result" : [
{
"_id" : ObjectId("56116d8e4a0000c9006b57ac"),
"items" : [
{
"price" : 1.10,
"desc" : "Item 3"
},
{
"price" : 1.50,
"desc" : "Item 1"
},
{
"price" : 1.70,
"desc" : "Item 2"
}
]
}
],
"ok" : 1
How do I just get Item 3 (the cheapest)? This is the result I'm looking for:
{
"price" : 1.10,
"desc" : "Item 3"
}
Upvotes: 0
Views: 139
Reputation: 2923
Use the $first operator instead of $push, then do a $project:
db.stock.wip.aggregate([
{$unwind: "$items"},
{$sort: {"items.price":1}},
{$group: {_id:"$_id", items: {$first:"$items"}}},
{ $project: {
_id: 0,
price: "$items.price",
desc: "$items.desc",
}}
]);
If you want to limit results only to the first item on the collection, add a {$limit:1} operator after the $sort:
db.stock.wip.aggregate([
{$unwind: "$items"},
{$sort: {"items.price":1}},
{$limit:1},
{$group: {_id:"$_id", items: {$first:"$items"}}},
{ $project: {
_id: 0,
price: "$items.price",
desc: "$items.desc",
}}
]);
Upvotes: 1
Reputation: 5918
I managed to write an aggregation query starting from your own, by slightly changed the $group
stage and adding an additional $project
step:
db.stock.wip.aggregate([
{$unwind: "$items"},
{$sort: {"items.price":1}},
{$group: {
_id:null,
lowestItem: {$first:"$items"}}},
{$project: {_id: 0, price: "$lowestItem.price", desc: "$lowestItem.desc"}}
]);
Upvotes: 1