Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I $add over a list of fields that may not exist

I have a document with the structure below, and I want to get a total for the last 2 months adding 2013.5 and 2013.4, as part of the process of getting the top 10 packages.

If I use the aggregate

db.hits.aggregate(
    {$project:{"total":{"$add":["$value.2013.5", "$value.2013.4"]}}})

this will return a numeric value in total only if both the fields exist in a document. If any of the fields are missing, total has the value null. Any ideas how I can navigate around this. There are $group, $sort, $limit following on from $project, but I've omitted them for clarity.

{
  "_id" : "4e6eef33-d88a-4d4d-a6b2-6becf1be7e8f",
  "value" : {
    "package" : 4498
    "2012" : {
      "1" : 1.0,
      "2" : 1.0,
      "4" : 1.0,
      "6" : 4.0,
      "7" : 2.0,
      "8" : 5.0,
      "12" : 1.0,
      "hits" : 15.0
    },
    "2013" : {
      "1" : 6.0,
      "4" : 2.0,
      "hits" : 8.0
    },
    "hits" : 23.0
  }
}

By the way, I use two months only for illustration. I'll normally be using 12 months.

Edit: My fallback is to write a function that adds the missing fields in the document. I'm interested if there's a way I can avoid doing that.

like image 744
Keith Marsh Avatar asked Mar 24 '23 22:03

Keith Marsh


1 Answers

this will return a numeric value in total only if both the fields exist in a document.

If one of the fields don't exist, then this is treated like undefined. undefined value is propagated in any operation.

If I use the aggregate [...]

You could use the $ifNull operator:

db.hits.aggregate({$project:{"total":{"$add":[{$ifNull: ["$value.2013.5", 0]}, {$ifNull: ["$value.2013.4", 0]}]}}})
like image 166
vinipsmaker Avatar answered Mar 26 '23 16:03

vinipsmaker