Reputation: 27
there
My question may be confuse. Let's me explain further more.
I have document for aggregation like this.
{
"metric" : "user_act",
"stream_id" : "f00001",
"values" : {
"likes" : 57,
"comments" : 0,
"shares" : 0
}
}
{
"metric" : "user_act",
"stream_id" : "f00002",
"values" : {
"likes" : 28,
"comments" : 0,
"shares" : 1
}
}
{
"metric" : "user_act",
"stream_id" : "t00001",
"values" : {
"favorites" : 5,
"retweets" : 15
}
}
I would like to calculate engagement by sum likes, comments and shares together. So before calculating, I have to projection data before grouping. I would like to mapping values.favorites
to likes
, values.retweets
to shares
and comments
if don't have any data set default to 0.
I try projection like below but does not work because value of second line of $ifNull
override the first line.
{
$project: {
"stream_id" : 1,
"shares": {
$ifNull: ["$values.retweets",0],
$ifNull: ["$values.shares", 0]
} ,
"likes": {
$ifNull: ["$values.favorites",0],
$ifNull: ["$values.likes", 0]
} ,
"comments": {
$ifNull: ["$values.replys",0],
$ifNull: ["$values.comments", 0]
}
}
}
Anyone any idea? Thank you in advanced.
[Update]
I try to projection like this but not work in case:
how can I check the field exists?
{
$project: {
"stream_id" : 1,
"shares": {
$switch: {
branches: [
{ case: {$ne: ["$values.retweets", 0]},
then: {$ifNull: ["$values.retweets", "$values.retweets"]}
},
{ case: {$ne: ["$values.shares", 0]},
then: {$ifNull: ["$values.shares", "$values.shares"]}
}
],
default: 0
}
}
}
}
Upvotes: 2
Views: 166
Reputation: 75994
You can try $cond
projection.
db.collection.aggregate({
$project: {
"stream_id" : 1,
"shares": { $cond: [ { $eq:[ { $ifNull: [ "$values.shares", 0 ] }, 0 ] },{ $ifNull: [ "$values.retweets", 0 ] }, "$values.shares" ] },
"likes": { $cond: [ { $eq:[ { $ifNull: [ "$values.likes", 0 ] }, 0 ] }, { $ifNull: [ "$values.favorites", 0 ] }, "$values.likes" ] },
"comments": { $cond: [ { $eq:[ { $ifNull: [ "$values.comments", 0] }, 0 ] }, { $ifNull: [ "$values.replys", 0 ] }, "$values.comments" ] }
}})
Using $switch
db.collection.aggregate([{
$project: {
"stream_id" : 1,
"shares": {
$switch: {
branches: [
{ case: { $ifNull: [ "$values.shares", false ] },
then: "$values.shares"
},
{ case: { $ifNull: [ "$values.retweets", false ] },
then: "$values.retweets"
}],
default: 0
}
}
}
}])
Upvotes: 1