I have many documents called 'Item' in the following form:
Item = {
"_id" : ObjectId("6059f025fb8378a294180cc3"),
"name" : "My Name",
"category" : "My Category",
"marketData" : {
"currency" : "€",
"history" : [
{
"timestamp" : 1,
"price" : 1.1,
"volume" : 10
},
{
"timestamp" : 3,
"price" : 2.2,
"volume" : 20
},
]
}
}
The history has a different length and each document has different timestamps, some documents will share a few timestamps.
I need the sum of prices and volume for each timestamp of each category. Like this:
Categories =
[{
"_id",
"name": "My Category",
"marketData": {
"currency": "€",
"history": [
{
"timestamp": 1,
"price": "sum of prices of all items at timestamp 1",
"volume": "sum of volume of all items at timestamp 1"
},
...
]
}
},
...
]
I have already tried this but it said SyntaxError: invalid property id
db.items.aggregate([
{ $unwind: "$marketData.history" },
{
$group: {
_id: "$marketData.history.timestamp",
price: { $sum:"$marketData.history.price" }
},
{
$group: {
_id:null,
price: {
$push: { timestamp: "$timestamp", price:"$price" }
}
}
},
{
$project: {
marketData.history:1,
_id:0
}
}
}
])
SOLUTION 1 : If you just want to group your data.
db.items.aggregate([
{ $unwind: "$marketData.history" },
{
$group: {
_id: {
category: "$category",
timestamp: "$marketData.history.timestamp"
},
price: { $sum: "$marketData.history.price" },
volume: { $sum: "$marketData.history.volume" }
}
},
{
$project: {
_id: 0,
category: "$_id.category",
timestamp: "$_id.timestamp",
price: "$price",
volume: "$volume"
}
},
{
$group: {
_id: null,
result: { $push: "$$ROOT" }
}
}
]);
SOLUTION 2 : To exactly match your expected output.
db.items.aggregate([
{ $unwind: "$marketData.history" },
{
$group: {
_id: {
category: "$category",
timestamp: "$marketData.history.timestamp"
},
name: { $first: "$name" },
currency: { $first: "$marketData.currency" },
price: { $sum: "$marketData.history.price" },
volume: { $sum: "$marketData.history.volume" }
}
},
{
$sort: { "_id.timestamp": 1 }
},
{
$group: {
_id: "$_id.category",
category: { $first: "$_id.category" },
name: { $first: "$name" },
currency: { $first: "$currency" },
history: {
$push: {
timestamp: "$_id.timestamp",
price: "$price",
volume: "$volume"
}
}
}
},
{
$addFields: {
marketData: {
currency: "$currency",
history: "$history"
},
currency: "$$REMOVE",
history: "$$REMOVE"
}
}
]);
Output:
/* 1 */
{
"_id" : "My Category",
"category" : "My Category",
"name" : "My Name",
"marketData" : {
"currency" : "€",
"history" : [
{
"timestamp" : 1,
"price" : 10,
"volume" : 20
},
{
"timestamp" : 3,
"price" : 2.2,
"volume" : 20
}
]
}
},
/* 2 */
{
"_id" : "My Category 2",
"category" : "My Category 2",
"name" : "My Name 2",
"marketData" : {
"currency" : "€",
"history" : [
{
"timestamp" : 1,
"price" : 1.1,
"volume" : 10
},
{
"timestamp" : 3,
"price" : 2.2,
"volume" : 20
}
]
}
}
Also you are getting that error because there is an extra closing }
brace and marketData.history
is not enclosed as "marketData.history"
. Check the corrected query below:
db.items.aggregate([
{ $unwind: "$marketData.history" },
{
$group: {
_id: "$marketData.history.timestamp",
price: { $sum: "$marketData.history.price" }
}
},
{
$group: {
_id: null,
price: {
$push: { timestamp: "$_id", price: "$price" }
}
}
},
{
$project: { _id: 0 }
}
])
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.