Mongo query to group and calculate average with group by - mongodb

I have a mongo collection mytopic with the following structure:
id : ObjectId
host: String
analytics: Object
topic_count : Array
name: String
mentions: Int
duration: Float
percentage: Float
I want to group by analytics.topic_count.name and return the average of duration for each user.
My expected output is :
Topic1: User1: <Average of duration for Topic1>
User2: <float>
User3: <float>
User4: <float>
User5: <float>
Topic2 User1: <float>
User2: <float>
User3: <float>
User4: <float>
User5: <float>
is it possible to get this kind of output. I am new to mongo and totally lost on this query. Any help is appreciated.
Thanks
Here is a partial export of my db collection:
[{
"_id": {
"$oid": "5edfd7a9c7152c8e6c708482"
},
"host": "user1",
"analytics": {
"topic_count": [
{
"name": "Topic1",
"mentions": 12,
"duration": 160.94,
"percentage": 5.76
},
{
"name": "Topic4",
"mentions": 9,
"duration": 108.14,
"percentage": 3.87
},
{
"name": "Topic3",
"mentions": 3,
"duration": 48.52,
"percentage": 1.74
},
{
"name": "Topic2",
"mentions": 8,
"duration": 95.5,
"percentage": 3.42
},
{
"name": "Topic5",
"mentions": 2,
"duration": 2.43,
"percentage": 0.09
},
{
"name": "Topic6",
"mentions": 4,
"duration": 55.75,
"percentage": 1.99
},
{
"name": "Topic7",
"mentions": 4,
"duration": 53.33,
"percentage": 1.91
},
{
"name": "Topic8",
"mentions": 4,
"duration": 45.37,
"percentage": 1.62
}
]
}
},{
"_id": {
"$oid": "5edfd7a9c7152c8e6c708483"
},
"host": "user1",
"analytics": {
"topic_count": [
{
"name": "Topic1",
"mentions": 14,
"duration": 209.85,
"percentage": 7.13
},
{
"name": "Topic4",
"mentions": 9,
"duration": 97.27,
"percentage": 3.31
},
{
"name": "Topic3",
"mentions": 3,
"duration": 37.13,
"percentage": 1.26
},
{
"name": "Topic2",
"mentions": 4,
"duration": 52.46,
"percentage": 1.78
},
{
"name": "Topic5",
"mentions": 2,
"duration": 3.13,
"percentage": 0.11
},
{
"name": "Topic6",
"mentions": 4,
"duration": 34,
"percentage": 1.16
},
{
"name": "Topic7",
"mentions": 4,
"duration": 79.9,
"percentage": 2.72
},
{
"name": "Topic8",
"mentions": 4,
"duration": 87.45,
"percentage": 2.97
}
]
}
},{
"_id": {
"$oid": "5edfd7a9c7152c8e6c708484"
},
"host": "user1",
"analytics": {
"topic_count": [
{
"name": "Topic1",
"mentions": 12,
"duration": 165.19,
"percentage": 5.91
},
{
"name": "Topic4",
"mentions": 9,
"duration": 112.15,
"percentage": 4.01
},
{
"name": "Topic3",
"mentions": 3,
"duration": 29.28,
"percentage": 1.05
},
{
"name": "Topic2",
"mentions": 4,
"duration": 46.74,
"percentage": 1.67
},
{
"name": "Topic5",
"mentions": 3,
"duration": 2.7,
"percentage": 0.1
},
{
"name": "Topic6",
"mentions": 4,
"duration": 17.59,
"percentage": 0.63
},
{
"name": "Topic7",
"mentions": 4,
"duration": 62.34,
"percentage": 2.23
},
{
"name": "Topic8",
"mentions": 4,
"duration": 57.62,
"percentage": 2.06
}
]
}
},{
"_id": {
"$oid": "5edfd7a9c7152c8e6c708485"
},
"host": "user1",
"analytics": {
"topic_count": [
{
"name": "Topic1",
"mentions": 12,
"duration": 226.65,
"percentage": 6.04
},
{
"name": "Topic4",
"mentions": 9,
"duration": 139.59,
"percentage": 3.72
},
{
"name": "Topic3",
"mentions": 3,
"duration": 44.85,
"percentage": 1.2
},
{
"name": "Topic2",
"mentions": 4,
"duration": 69.18,
"percentage": 1.84
},
{
"name": "Topic5",
"mentions": 2,
"duration": 18.07,
"percentage": 0.48
},
{
"name": "Topic6",
"mentions": 4,
"duration": 63.9,
"percentage": 1.7
},
{
"name": "Topic7",
"mentions": 4,
"duration": 57.19,
"percentage": 1.52
},
{
"name": "Topic8",
"mentions": 4,
"duration": 60.42,
"percentage": 1.61
}
]
}
},{
"_id": {
"$oid": "5edfd7a9c7152c8e6c708486"
},
"host": "user1",
"analytics": {
"topic_count": [
{
"name": "Topic1",
"mentions": 12,
"duration": 181.99,
"percentage": 6.31
},
{
"name": "Topic4",
"mentions": 9,
"duration": 102.66,
"percentage": 3.56
},
{
"name": "Topic3",
"mentions": 3,
"duration": 33.21,
"percentage": 1.15
},
{
"name": "Topic2",
"mentions": 4,
"duration": 55.31,
"percentage": 1.92
},
{
"name": "Topic5",
"mentions": 5,
"duration": 9.24,
"percentage": 0.32
},
{
"name": "Topic6",
"mentions": 4,
"duration": 35.82,
"percentage": 1.24
},
{
"name": "Topic7",
"mentions": 4,
"duration": 72.24,
"percentage": 2.51
},
{
"name": "Topic8",
"mentions": 4,
"duration": 30.3,
"percentage": 1.05
}
]
}
}]

Are you looking for something like this ?
db.collection.aggregate([
{
"$unwind": "$analytics.topic_count"
},
{
"$group": {
"_id": {
topic: "$analytics.topic_count.name",
host: "$host"
},
"duration": {
"$avg": "$analytics.topic_count.duration"
}
}
},
{
"$group": {
"_id": "$_id.topic",
"durations": {
"$addToSet": {
"$mergeObjects": [
{
"host": "$_id.host"
},
{
"duration": "$duration"
}
]
}
}
}
}
])
Here is working Mongo Playground

Related

MongoDB Aggregation Pipeline help (Convert MySQL to Mongo)

I know these have been asked a bunch and I am brand new to MongoDB which means I am struggling. I am using compass and trying to figure out this aggregation pipeline. In short, I need to get the average time difference between the max and min timestamp grouped by id.
The expected result would just be: avg_time: 234.00 or such.
The equivalent MySQL query looks like this:
select SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(a.maxDate,a.minDate)))) FROM (select id, min(timestamp) as minDate, max(timestamp) as maxDate from counterHistory group by id) as a
Here is what the dataset looks like:
[{
"_id": {
"$oid": "617dce992743dd52bed811a6"
},
"dateStart": {
"$date": "2021-10-30T23:00:41.056Z"
},
"dateEnd": {
"$date": "2021-10-30T23:00:52.404Z"
},
"areas": {
"c2acc5cc-9a7a-4406-8d91-79cb7f7ded70": {
"color": "yellow",
"type": "rightleft_bottomtop",
"location": {
"point1": {
"x": 1397,
"y": 702
},
"point2": {
"x": 1808,
"y": 645
},
"refResolution": {
"w": 1920,
"h": 969
}
},
"computed": {
"a": 0.15457277801631616,
"b": -332.7843438566361,
"lineBearings": [
81.21317228796154,
261.2131722879615
],
"point1": {
"x": 465.6666666666667,
"y": -260.80495356037153
},
"point2": {
"x": 602.6666666666666,
"y": -239.62848297213623
}
},
"name": "Right line start"
},
"56885eaf-9808-4b5e-b193-06b20e10c39d": {
"color": "turquoise",
"type": "rightleft_bottomtop",
"location": {
"point1": {
"x": 770,
"y": 411
},
"point2": {
"x": 1085,
"y": 360
},
"refResolution": {
"w": 1920,
"h": 969
}
},
"computed": {
"a": 0.18045112781954886,
"b": -199.0092879256966,
"lineBearings": [
79.77099171264048,
259.77099171264047
],
"point1": {
"x": 256.6666666666667,
"y": -152.6934984520124
},
"point2": {
"x": 361.6666666666667,
"y": -133.74613003095976
}
},
"name": "right lane end"
}
},
"videoResolution": {
"w": 640,
"h": 360
},
"filename": "demo.mp4",
"counterSummary": {
"56885eaf-9808-4b5e-b193-06b20e10c39d": {
"_total": 8,
"car": 8
},
"c2acc5cc-9a7a-4406-8d91-79cb7f7ded70": {
"_total": 8,
"car": 7,
"truck": 1
}
},
"trackerSummary": {
"totalItemsTracked": 64
},
"counterHistory": [
{
"frameId": 29,
"timestamp": {
"$date": "2021-10-30T23:00:42.694Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 408,
"bearing": 291.8014094863518,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 30.588237198390278
},
{
"frameId": 43,
"timestamp": {
"$date": "2021-10-30T23:00:43.619Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "truck",
"id": 457,
"bearing": 293.1985905136482,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 31.985418225686644
},
{
"frameId": 50,
"timestamp": {
"$date": "2021-10-30T23:00:44.063Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 421,
"bearing": 303.69006752597977,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 43.919075813339305
},
{
"frameId": 63,
"timestamp": {
"$date": "2021-10-30T23:00:44.927Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 458,
"bearing": 293.6293777306568,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 32.41620544269528
},
{
"frameId": 65,
"timestamp": {
"$date": "2021-10-30T23:00:45.054Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 464,
"bearing": 284.03624346792645,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 24.265251755286005
},
{
"frameId": 78,
"timestamp": {
"$date": "2021-10-30T23:00:45.888Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 469,
"bearing": 303.69006752597977,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 42.47689523801825
},
{
"frameId": 86,
"timestamp": {
"$date": "2021-10-30T23:00:46.415Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 427,
"bearing": 354.28940686250036,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 85.48158485014012
},
{
"frameId": 122,
"timestamp": {
"$date": "2021-10-30T23:00:48.757Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 479,
"bearing": 296.565051177078,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 35.35187888911645
},
{
"frameId": 125,
"timestamp": {
"$date": "2021-10-30T23:00:48.946Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 408,
"bearing": 323.13010235415595,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 63.359110641515514
},
{
"frameId": 143,
"timestamp": {
"$date": "2021-10-30T23:00:50.143Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 473,
"bearing": 284.03624346792645,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 24.265251755286005
},
{
"frameId": 152,
"timestamp": {
"$date": "2021-10-30T23:00:50.716Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 438,
"bearing": 296.565051177078,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 35.35187888911645
},
{
"frameId": 160,
"timestamp": {
"$date": "2021-10-30T23:00:51.242Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 455,
"bearing": 45,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 34.77099171264047
},
{
"frameId": 174,
"timestamp": {
"$date": "2021-10-30T23:00:52.149Z"
},
"area": "c2acc5cc-9a7a-4406-8d91-79cb7f7ded70",
"name": "car",
"id": 492,
"bearing": 327.2647737278924,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 66.05160143993088
},
{
"frameId": 175,
"timestamp": {
"$date": "2021-10-30T23:00:52.212Z"
},
"area": "56885eaf-9808-4b5e-b193-06b20e10c39d",
"name": "car",
"id": 469,
"bearing": 281.30993247402023,
"countingDirection": "rightleft_bottomtop",
"angleWithCountingLine": 21.538940761379738
}
]
}]
Here is my atrocious pipeline that at least gives me the result that I am looking for. So I guess, how do you optimize this?
[{$match: {
_id:ObjectId('617dce992743dd52bed811a6')
}}, {$unwind: {
path: "$counterHistory",
}}, {$group: {
_id: "$counterHistory.id",
maxDate:{$max:"$counterHistory.timestamp"},
minDate:{$min:"$counterHistory.timestamp"}
}}, {$project: {
_id:1,
minDate:1,
maxDate:1,
noMatchingDates:{$ne:["$maxDate","$minDate"]}
}}, {$match: {
noMatchingDates:true
}}, {$group: {
_id: null,
"avg_time": {
"$avg": {
"$subtract": [
{ "$ifNull": [ "$maxDate", 0 ] },
{ "$ifNull": [ "$minDate", 0 ] }
]
}
}
}}, {$project: {
avg_time:1,
hours: { $divide: [ "$avg_time", 3600000 ] },
minutes: { $divide: [ "$avg_time", 60000 ] },
seconds: { $divide: [ "$avg_time", 1000 ] }
}}]
So as I put up above and confirmed by YuTing, this pipeline works:
[{$match: {
_id:ObjectId('617dce992743dd52bed811a6')
}}, {$unwind: {
path: "$counterHistory",
}}, {$group: {
_id: "$counterHistory.id",
maxDate:{$max:"$counterHistory.timestamp"},
minDate:{$min:"$counterHistory.timestamp"}
}}, {$project: {
_id:1,
minDate:1,
maxDate:1,
noMatchingDates:{$ne:["$maxDate","$minDate"]}
}}, {$match: {
noMatchingDates:true
}}, {$group: {
_id: null,
"avg_time": {
"$avg": {
"$subtract": [
{ "$ifNull": [ "$maxDate", 0 ] },
{ "$ifNull": [ "$minDate", 0 ] }
]
}
}
}}, {$project: {
avg_time:1,
hours: { $divide: [ "$avg_time", 3600000 ] },
minutes: { $divide: [ "$avg_time", 60000 ] },
seconds: { $divide: [ "$avg_time", 1000 ] }
}}]

mongodb update where argument exists

db.filmes.insertMany(
[
{
"num": 1,
"title": "movie1",
"category": "Horror",
"review": 5,
"cast": {
"director": "R1",
"artist": "A1"
},
"exibition": [
"Lisboa",
"Porto",
"Braga"
]
},
{
"num": 2,
"title": "movie2",
"category": "Action",
"review": 3,
"cast": {
"director": "R2",
"artist": "A2"
},
"exibition": [
"Lisboa",
"Porto"
]
},
{
"num": 3,
"title": "movie3",
"category": "Animation",
"review": 3,
"cast": {
"director": "R2",
"artist": "A2"
},
"exibition": [
"Lisboa",
"Porto",
"Viseu"
]
},
{
"num": 4,
"title": "movie4",
"category": "Animation",
"review": 6,
"cast": {
"director": "R1",
"artist": "A4"
},
"exibition": [
"Lisboa",
"Porto",
"Braga"
]
},
{
"num": 5,
"title": "movie5",
"category": "Horror",
"review": 5,
"cast": {
"director": "R3",
"artist": "A3"
},
"exibition": [
"Lisboa",
"Porto"
]
}
]);
I need to update all the reviews to 10 where artist "A3" appears?
I already tried :
db.movies.updateMany({cast:{artist:"A3"}},{$set:{review:10}})
db.movies.update({artist:"A3"},{$ste:{review:10}});
and other that I cant remember,
there's is a way to do it ?

Mongdb aggregate do second group inside first group stage output

I don't know if it's either possible but I would like to obtain a specific output from an aggregate pipeline.
Exemples objects:
{
"_id": "6001d736e6dc1c55e893158d",
"manager": "6000da590ed6253807158216",
"label": "Test",
"identifier": "Test",
"interval": 11,
"unit": "X",
"created_at": "2021-01-15T17:56:06.749Z",
"updated_at": "2021-01-21T12:21:35.670Z",
"__v": 0
},
{
"_id": "6030236f976756b0b2d74556",
"manager": "6022f3285752fec73393bda2",
"label": "Temperature salon",
"identifier": "DS18B20_TEMP",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-19T20:45:35.847Z",
"updated_at": "2021-02-19T20:45:35.847Z",
"__v": 0
}
I'm trying to obtain a group by date AND by unit(field in object), i succeed to do it separatly but i can't find a solution to do both in the same pipeline.
Expected output if i do the first group by month:
{
"_id": "2021-01-00T00:00:00.000Z",
"X": objectsArray[],
"°C": objetcsArray[]
},
{
"_id": "2021-02-00T00:00:00.000Z",
"X": objectsArray[],
"°C": objetcsArray[]
}
What i have for the moment with this group:
{
'_id': {
'$add': [
{ '$subtract': [
{ '$subtract': [ '$created_at', new Date(0) ] },
{ '$mod': [
{ '$subtract': [ '$created_at', new Date(0) ] },
this.millisecondsIn(interval),
]},
]},
new Date(0),
]
},
sensors: {
$addToSet: '$$ROOT',
},
}
{
"_id": "2021-01-21T00:00:00.000Z",
"sensors": [
{
"_id": "601ab8f623224a5387c6252d",
"manager": "6000da590ed6253807158216",
"label": "Test",
"identifier": "Test2",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-03T14:53:42.538Z",
"updated_at": "2021-02-03T14:53:42.538Z",
"__v": 0
},
{
"_id": "6029ad3dda9bafb99cf0b4d5",
"manager": "6022f3285752fec73393bda2",
"label": "Test sensor 1",
"identifier": "RANDOMID",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-14T23:07:41.255Z",
"updated_at": "2021-02-14T23:07:41.255Z",
"__v": 0
}
]
},
{
"_id": "2020-12-24T00:00:00.000Z",
"sensors": [
{
"_id": "6001917f41c38212a477a2ce",
"manager": "6000da590ed6253807158216",
"label": "Test label",
"identifier": "TEst id",
"interval": 10,
"unit": "%",
"created_at": "2021-01-15T12:58:39.514Z",
"updated_at": "2021-01-16T19:08:40.239Z",
"__v": 0
},
{
"_id": "6001d736e6dc1c55e893158d",
"manager": "6000da590ed6253807158216",
"label": "Test",
"identifier": "Test",
"interval": 11,
"unit": "X",
"created_at": "2021-01-15T17:56:06.749Z",
"updated_at": "2021-01-21T12:21:35.670Z",
"__v": 0
}
]
},
{
"_id": "2021-02-18T00:00:00.000Z",
"sensors": [
{
"_id": "6030238d976756b0b2d74557",
"manager": "6022f3285752fec73393bda2",
"label": "Taux d'humidité salon",
"identifier": "DHT_22_HUM",
"interval": 60,
"unit": "%",
"created_at": "2021-02-19T20:46:05.042Z",
"updated_at": "2021-02-19T20:46:05.042Z",
"__v": 0
},
{
"_id": "60302357976756b0b2d74555",
"manager": "6022f3285752fec73393bda2",
"label": "Temperature salon",
"identifier": "DTH_22_TEMP",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-19T20:45:11.071Z",
"updated_at": "2021-02-19T20:45:11.071Z",
"__v": 0
},
{
"_id": "6030236f976756b0b2d74556",
"manager": "6022f3285752fec73393bda2",
"label": "Temperature salon",
"identifier": "DS18B20_TEMP",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-19T20:45:35.847Z",
"updated_at": "2021-02-19T20:45:35.847Z",
"__v": 0
}
]
}
Does anyone know if the wanted output is possible and if it is, how ?
Thanks
The general steps would be:
$group by unit and date, pushing all of the documents into a sensors array
$project to create a new field with {k: <unit value>, v: <sensors array>}
$group by date, pushing the new field into an array
$project with $arrayToObject to convert array
$addFields to include the date in the new object
$replaceRoot to promote the new object
Thank you so much Joe, after few hours and many tries I end up with this:
this.sensorModel
.aggregate()
.group({
'_id': {
date: { '$year': '$created_at' },
'unit': '$unit',
},
test: { '$addToSet': '$$ROOT' },
})
.project({
newField: {
k: '$_id.unit',
v: '$test',
}
})
.group({
'_id': '$_id.date',
data: { '$addToSet': '$newField', },
})
.project({
'sensors': { $arrayToObject: '$data', },
})
.replaceRoot({
$arrayToObject: [[{k: {$toString: '$_id'}, v: '$sensors'}]]
})
.exec();
The result is almost perfect:
[
{
"2021": {
"°C": [
{
"_id": "6029ad3dda9bafb99cf0b4d5",
"manager": "6022f3285752fec73393bda2",
"label": "Test sensor 1",
"identifier": "RANDOMID",
"interval": 60,
"unit": "°C",
"created_at": "2021-02-14T23:07:41.255Z",
"updated_at": "2021-02-14T23:07:41.255Z",
"__v": 0
},
],
"X": [
{
"_id": "6001d736e6dc1c55e893158d",
"manager": "6000da590ed6253807158216",
"label": "Test",
"identifier": "Test",
"interval": 11,
"unit": "X",
"created_at": "2021-01-15T17:56:06.749Z",
"updated_at": "2021-01-21T12:21:35.670Z",
"__v": 0
}
],
"%": [
{
"_id": "6030238d976756b0b2d74557",
"manager": "6022f3285752fec73393bda2",
"label": "Taux d'humidité salon",
"identifier": "DHT_22_HUM",
"interval": 60,
"unit": "%",
"created_at": "2021-02-19T20:46:05.042Z",
"updated_at": "2021-02-19T20:46:05.042Z",
"__v": 0
},
]
}
}
]

Rating-Feature in MongoDB - Percent and get count for each of their ratings

I have a rating model for my posts and the rating value for them. I would like to receive all ratings (ratings vary from 1 to 5) for each post in the database. I would also like to receive a percentage
https://mongoplayground.net/p/tDvZ8qLQ1m8
My scheme just looks like:
{
"_id": 1,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"author": ObjectId("5eefd305d9020c52fd81f80d"),
"rating": 1,
},
{
"_id": 2,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 1,
},
{
"_id": 3,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 1,
},
{
"_id": 4,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 5,
},
{
"_id": 5,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 3,
},
{
"_id": 6,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 2,
},
{
"_id": 7,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 2,
},
{
"_id": 8,
"post": ObjectId("5ee40fbc1617af52edf81682"),
"rating": 2,
}
]
My Code:
{
$match: {
post: ObjectId("5ee40fbc1617af52edf81682")
}
},
{
"$group": {
"_id": {
"post": "$name",
"rating": "$rating"
},
"count": {
"$sum": 1
},
}
},
{
"$group": {
"_id": "$_id.post",
"counts": {
"$push": {
"rating": "$_id.rating",
"result": "$count",
"percent": "percent",
}
}
}
}
])
My Result:
{
"_id": null,
"counts": [
{
"percent": "percent",
"rating": 2,
"result": 3
},
{
"percent": "percent",
"rating": 3,
"result": 1
},
{
"percent": "percent",
"rating": 5,
"result": 1
},
{
"percent": "percent",
"rating": 1,
"result": 3
}
]
}
]
My preferred result
{
"_id": null,
"ratingAll": 8,
"ratingAvg": [[rating-average]],
"counts": [
{
"rating": 1,
"result": 3,
"percent": [[percentValue]],
},
{
"rating": 2,
"result": 3,
"percent": [[percentValue]],
},
{
"rating": 3,
"result": 1,
"percent": [[percentValue]],
},
{
"rating": 4,
"result": 0,
"percent": [[percentValue]],
},
{
"rating": 5,
"result": 1,
"percent": [[percentValue]],
}
]
}
]

merge two objects of different collections and get specific data in Mongodb

I have two collections, products and orders.
products collection look like this.
[
{
"_id": "5efb56741c32133bf43ea9aa",
"title": "Xyz",
"image": "172e4eb73415b3cc8540e651.jpg",
"quantity": "1 Ltr",
"price": 1500,
"status": true,
"creationDate": "2020-06-30T15:12:52.570Z",
"__v": 0
},
{
"_id": "5f0079bd27a734424cb3069a",
"title": "abc",
"image": "122e4eb73413b3cc854n42n1.jpg",
"quantity": "500 ml",
"price": 700,
"status": true,
"creationDate": "2020-06-30T15:12:52.570Z",
"__v": 0
}
]
orders collection look like this.
[
{
"_id": "5efca937def27b74fc9f6aa6",
"products": [
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca937def27b74fc9f6aa8",
"productId": "5efb56741c32133bf43ea9aa",
"productQuantity": 2
},
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca937def27b74fc9f6aa7",
"productId": "5f0079bd27a734424cb3069a",
"productQuantity": 1
}
],
"totalQuantity": 3,
"totalPrice": 3700,
"creationDate": "2020-07-01T15:18:15.756Z",
"__v": 0
},
{
"_id": "5efca897def27b74fc9f6aa2",
"products": [
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca897def27b74fc9f6aa3",
"productId": "5f0079bd27a734424cb3069a",
"productQuantity": 1
}
],
"totalQuantity": 1,
"totalPrice": 700,
"creationDate": "2020-07-01T15:15:35.422Z",
"__v": 0
}
]
using this two collections how can I get result like this:
[
{
"_id": "5efca937def27b74fc9f6aa6",
"products": [
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca937def27b74fc9f6aa8",
"productId": "5efb56741c32133bf43ea9aa",
"productQuantity": 2,
"title": "Xyz",
"image": "172e4eb73415b3cc8540e651.jpg",
"quantity": "1 Ltr",
"price": 1500
},
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca937def27b74fc9f6aa7",
"productId": "5f0079bd27a734424cb3069a",
"productQuantity": 1,
"title": "abc",
"image": "122e4eb73413b3cc854n42n1.jpg",
"quantity": "500 ml",
"price": 700
}
],
"totalQuantity": 3,
"totalPrice": 3700,
"creationDate": "2020-07-01T15:18:15.756Z",
"__v": 0
},
{
"_id": "5efca897def27b74fc9f6aa2",
"products": [
{
"Date": "2020-07-01T15:14:36.630Z",
"_id": "5efca897def27b74fc9f6aa3",
"productId": "5f0079bd27a734424cb3069a",
"productQuantity": 1,
"title": "abc",
"image": "122e4eb73413b3cc854n42n1.jpg",
"quantity": "500 ml",
"price": 700
}
],
"totalQuantity": 1,
"totalPrice": 700,
"creationDate": "2020-07-01T15:15:35.422Z",
"__v": 0
}
]
I got the result using this query.
order.aggregate([
{ "$unwind": "$products" },
{
$lookup: {
from: 'products',
localField: "products.productId",
foreignField: "_id",
as: "product"
}
},
{
"$addFields": {
"products": { $mergeObjects: [{ $arrayElemAt: ["$product", 0] }, "$$ROOT.products"] }
}
},
{
"$group": {
"_id": "$_id",
"products": { "$push": "$products" },
"totalQuantity": { $first: '$totalQuantity' },
"totalPrice": { $first: '$totalPrice' },
"creationDate": { $first: '$creationDate' }
}
}
])