$sum arrays with the same ids in mongodb - mongodb

The two documents of my collection look like this:
First document
{
"_id" : 2055,
"counervalues" : {
"chcounter" : 3
"bscounter" : 10
}
"attributionvalues" :[
{
"id" : 1
"conversionvalue" : 85.0
"conversioncounter" : 6300.0
},
{
"id" : 2
"conversionvalue" : 25.0
"conversioncounter" : 600
}
}
Second document
{
"_id" : 1046,
"counervalues" : {
"chcounter" : 23
"bscounter" : 46
}
"attributionvalues" :[
{
"id" : 1
"conversionvalue" : 15.0
"conversioncounter" : 275.0
},
{
"id" : 2
"conversionvalue" : 65.0
"conversioncounter" : 12000.0
}
}
Now I want to apply the aggregation framework in order to get a new document which has a result as this:
Result
{
"_id" : 3005,
"counervalues" : {
"chcounter" : 26
"bscounter" : 56
}
"attributionvalues" :[
{
"id" : 1
"conversionvalue" : 100.0
"conversioncounter" : 6575.0
},
{
"id" : 2
"conversionvalue" : 90.0
"conversioncounter" : 12600.0
}
}
I started my aggregation like this:
db.conversion.counters.aggregate({
$match:
{
"_id" : {"$gte" : 1046 , "$lte" : 2055}
}
$group:
{
cvchc: {$sum: "$counervalues.chcounter"}
cvbsc: {$sum: "$counervalues.bscounter"}
}
});
but I have trouble to match the attributionvalues according to their ids and add them.
Anyone has an idea?

Run the following aggregation pipeline, should give you the desired results:
db.conversion.aggregate([
{ "$match": { "_id" : { "$gte" : 1046 , "$lte" : 2055 } } },
{ "$unwind": "$attributionvalues" },
{
"$group": {
"_id": "$attributionvalues.id",
"cvchc": { "$sum": "$counervalues.chcounter" },
"cvbsc": { "$sum": "$counervalues.bscounter" },
"avcv": { "$sum": "$attributionvalues.conversionvalue" },
"avcc": { "$sum": "$attributionvalues.conversioncounter" }
}
},
{
"$group": {
"_id": null,
"chcounter": { "$first": "$cvchc" },
"bscounter" : { "$first": "$cvbsc" },
"attributionvalues": {
"$push": {
"id": "$_id",
"conversionvalue": "$avcv" ,
"conversioncounter": "$avcc"
}
}
}
},
{
"$project": {
"counervalues": {
"chcounter": "$chcounter",
"bscounter": "$bscounter"
},
"attributionvalues": 1
}
}
])

Related

MongoDB get user which are new today

I am trying to find a user list which is new for day-1. I have written the query to find the users who arrived till the day before yesterday and the list of users arrived yesterday. Now I want minus those data how can I do that in a single aggregate function.
Function to get the list before yesterday
db.chat_question_logs.aggregate([
{
$match : {"createdDate":{$lte: ISODate("2020-04-29T00:00:00Z")}}
},
{
"$project" :
{
_id : 0,
"userInfo.userId":1
}
},
{
"$group": {
"_id": {userId:"$userInfo.userId"},"count": {$sum : 1}}
}
])
similarly for the day-1 is as below
db.chat_question_logs.aggregate([
{
$match : {"createdDate":{$gte: ISODate("2020-04-30T00:00:00Z"),$lte: ISODate("2020-05-01T00:00:00Z")}}
},
{
"$project" :
{
_id : 0,
"userInfo.userId":1
}
},
{
"$group": {
"_id": {userId:"$userInfo.userId"},"count": {$sum : 1}}
}
])
Result JSON are as below
/* 1 */
{
"_id" : {
"userId" : "2350202241750776"
},
"count" : 1
},
/* 2 */
{
"_id" : {
"userId" : "26291570771793121"
},
"count" : 1
},
/* 3 */
{
"_id" : {
"userId" : "2742872209107866"
},
"count" : 5
},
/* 4 */
{
"_id" : {
"userId" : "23502022417507761212"
},
"count" : 1
},
/* 5 */
{
"_id" : {
"userId" : "2629157077179312"
},
"count" : 43
}
How can I find the difference.
It sounds like what you want is to get all users created yesterday (which is the 28th in this example).
db.chat_question_logs.aggregate([
{
$match : { $and: [
{ "createdDate":{$lt: ISODate("2020-04-29T00:00:00Z")} },
{ "createdDate": {$gte: ISODate("2020-04-28T00:00:00Z") }}
] }
},
{
"$project" :
{
_id : 0,
"userInfo.userId":1
}
},
{
"$group": {
"_id": {userId:"$userInfo.userId"},"count": {$sum : 1}}
}
])
Is this what you want?
Hi found the solution which is below
I used the group and first appearance of the Id and then filter record on date which I wanted.The query is as below
db.chat_question_logs.aggregate([
{
$group:
{
_id: "$userInfo.userId",
firstApprance: { $first: "$createdDate" }
}
},
{
$match : { "firstApprance": { $gte: new ISODate("2020-05-03"), $lt: new ISODate("2020-05-05") } }
}
])

How to get percentage total of data with group by date in MongoDB

How to get percentage total of data with group by date in MongoDB ?
Link example : https://mongoplayground.net/p/aNND4EPQhcb
I have some collection structure like this
{
"_id" : ObjectId("5ccbb96706d1d47a4b2ced4b"),
"date" : "2019-05-03T10:39:53.108Z",
"id" : 166,
"update_at" : "2019-05-03T10:45:36.208Z",
"type" : "image"
}
{
"_id" : ObjectId("5ccbb96706d1d47a4b2ced4c"),
"date" : "2019-05-03T10:39:53.133Z",
"id" : 166,
"update_at" : "2019-05-03T10:45:36.208Z",
"type" : "image"
}
{
"_id" : ObjectId("5ccbb96706d1d47a4b2ced4d"),
"date" : "2019-05-03T10:39:53.180Z",
"id" : 166,
"update_at" : "2019-05-03T10:45:36.208Z",
"type" : "image"
}
{
"_id" : ObjectId("5ccbb96706d1d47a4b2ced4e"),
"date" : "2019-05-03T10:39:53.218Z",
"id" : 166,
"update_at" : "2019-05-03T10:45:36.208Z",
"type" : "image"
}
And I have query in mongodb to get data of collection, how to get percentage of total data. in bellow example query to get data :
db.name_collection.aggregate(
[
{ "$match": {
"update_at": { "$gte": "2019-11-04T00:00:00.0Z", "$lt": "2019-11-06T00:00:00.0Z"},
"id": { "$in": [166] }
} },
{
"$group" : {
"_id": {
$substr: [ '$update_at', 0, 10 ]
},
"count" : {
"$sum" : 1
}
}
},
{
"$project" : {
"_id" : 0,
"date" : "$_id",
"count" : "$count"
}
},
{
"$sort" : {
"date" : 1
}
}
]
)
and this response :
{
"date" : "2019-11-04",
"count" : 39
},
{
"date" : "2019-11-05",
"count" : 135
}
how to get percentage data total from key count ? example response to this :
{
"date" : "2019-11-04",
"count" : 39,
"percentage" : "22%"
},
{
"date" : "2019-11-05",
"count" : 135,
"percentage" : "78%"
}
You have to group by null to get total count and then use $map to calculate the percentage. $round will be a useful operator in such case. Finally you can $unwind and $replaceRoot to get back the same number of documents:
db.collection.aggregate([
// previous aggregation steps
{
$group: {
_id: null,
total: { $sum: "$count" },
docs: { $push: "$$ROOT" }
}
},
{
$project: {
docs: {
$map: {
input: "$docs",
in: {
date: "$$this.date",
count: "$$this.count",
percentage: { $concat: [ { $toString: { $round: { $multiply: [ { $divide: [ "$$this.count", "$total" ] }, 100 ] } } }, '%' ] }
}
}
}
}
},
{
$unwind: "$docs"
},
{
$replaceRoot: { newRoot: "$docs" }
}
])
Mongo Playground

How to count occurences of values in a nested array?

I've searched but could not find an answer to my problem. I need to count the occurences of the field "nationalCode". I've got a collection with this sample structure in MongoDB:
{
"_id" : ObjectId("5d7519cc6c17d65d4983f048"),
"origin" : "Base1",
"topic" : [
{
"nationalTopic" : {
"nationalCode" : 26
},
"dateTime" : NumberLong(20120927000000)
},
{
"nationalTopic" : {
"nationalCode" : 132
},
"dateTime" : NumberLong(20120927000000)
},
{
"nationalTopic" : {
"nationalCode" : 26
},
"dateTime" : NumberLong(20120927000000)
},
{
"nationalTopic" : {
"nationalCode" : 26
},
"dateTime" : NumberLong(20121005000000)
}
]
}
I've used the following code (I tried many variations of it, but none of them got me the right results):
db.processos.aggregate(
[
{ "$unwind": "$topic" },
{"$match": {"origin": "Base1"}},
{"$group": { "_id": { nationalCode: "$topic.nationalTopic.nationalCode", "count": { "$sum": 1 }} } }
]
)
I'm expecting something like this:
{
"_id" : {
"nationalCode" : 26,
"count" : 3.0
}
}
/* 2 */
{
"_id" : {
"nationalCode" : 132,
"count" : 1.0
}
}
You should extract the count element from the _id.
The following query worked for me.
db.data.aggregate(
[
{ "$unwind": "$topic" },
{"$match": {"origin": "Base1"}},
{"$group": { _id: { "nationalCode": "$topic.nationalTopic.nationalCode" },
"count": {$sum: 1} }
}
]
)
just do it with $project to change your format
do it like this
MongoDB Enterprise >
db.ggg.aggregate(
[
{$unwind:"$topic"},
{"$match": {"origin": "Base1"}},
{"$group": { "_id": { nationalCode: "$topic.nationalTopic.nationalCode"},
"count": { "$sum": 1 } }},
{$project :{"_id.nationalCode":1,"_id.count":"$count"}}
]
)
here it the result !
{ "_id" : { "nationalCode" : 26, "count" : 3 } }
{ "_id" : { "nationalCode" : 132, "count" : 1 } }

MongoDB - Sum value in nested array

I have an object looks like this
{
"_id" : {
"import_type" : "MANUAL_UPLOAD",
"supplier" : "jabino.de",
"unit_price" : "0"
},
"statuses" : [
{
"status" : "DUPLICATED",
"count" : 14
},
{
"status" : "BLACKLISTED",
"count" : 2
},
{
"status" : "USABLE",
"count" : 2239
},
{
"status" : "INVALID_EMAIL_ADDRESS",
"count" : 1
},
{
"status" : "DUPLICATED",
"count" : 14
},
{
"status" : "BLACKLISTED",
"count" : 2
},
{
"status" : "USABLE",
"count" : 2239
},
{
"status" : "INVALID_EMAIL_ADDRESS",
"count" : 1
}
]
}
How I can sum all the count in the statuses array which has the same status without losing keys-values in _id. E.g. in this case
Duplicated: 28
Blacklisted: 4
Usable: 4478
Invalid email address: 2
You can use below aggregation
db.collection.aggregate([
{ "$unwind": "$statuses" },
{ "$group": {
"_id": {
"_id": "$_id",
"statuses": "$statuses.status"
},
"count": { "$sum": "$statuses.count" }
}},
{ "$group": {
"_id": "$_id._id",
"statuses": {
"$push": {
"status": "$_id.statuses",
"count": "$count"
}
}
}}
])

mongodb aggregate and group with push

I am trying to push the data who is having minSalary using $push at group aggregate.
Query:
db.users.aggregate([
{ $match: { experience: { $gte:3, $lte:10} } },
{ $group: { _id: {totalExperience:"$experience"}, "count": {$sum:1},"minSalary": {$min:"$expected_salary"}, "minUsers": {$push:"$_id"}, "maxSalary": {$max:"$expected_salary"} } },
{ $sort: { '_id.totalExperience': -1 } }
])
Result
{
"_id" : {
"totalExperience" : 9
},
"count" : 549.0,
"minSalaryCount" : 120000,
"maxSalary" : 180000
}
Also i am expecting following result
{
"_id" : {
"totalExperience" : 9
},
"count" : 549.0,
"minSalaryCount" : 120000,
"maxSalary" : 180000,
"minSalaryUsers":[
ObjectId('5355345345sdrrw234234'),
ObjectId('5355345345sdeee234234'),
ObjectId('5355345345sdertw234234')
]
}
Thank you.