Search code examples
mongodbnosqlaggregation-frameworknosql-aggregation

MongoDB Aggregation leap-year


I am learning MongoDB NoSQL, and I have a problema about it.

Consider these documents:

{
    "_id" : ObjectId("63a994974ac549c5ea982d2b"),
    "title" : "Destroyer",
    "year" : 2018
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d2a"),
    "title" : "Aquaman",
    "year" : 2014
},

{
    "_id" : ObjectId("63a994974ac549c5ea982d29"),
    "title" : "On the Basis of Sex",
    "year" : 1996   
},

{
    "_id" : ObjectId("63a994974ac549c5ea982d28"),
    "title" : "Holmes and Watson",
    "year" : 1940
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d27"),
    "title" : "Conundrum: Secrets Among Friends",
    "year" : 1957
},
{
    "_id" : ObjectId("63a994974ac549c5ea982d26"),
    "title" : "Welcome to Marwen",
    "year" : 2000
},

{
    "_id" : ObjectId("63a994974ac549c5ea982d25"),
    "title" : "Mary Poppins Returns",
    "year" : 1997
},

{
    "_id" : ObjectId("63a994974ac549c5ea982d24"),
    "title" : "Bumblebee",
    "year" : 2004
},

I am trying to get all title that they have a leap year and I want to get the "count" of all title.

So, I tried this code:

var q1 = {$project: {
    leap: {
        "$and": [
                "$eq": ["$divide"["$year", 4], 0],
                {
                    "$or":[{"$ne": ["$divide"["$year",100],0]},
                    {"$eq": ["$divide"["$year", 400],0]}]
                }
            ]
    }
}}

var q2 = {$group: {"_id": null, "total": {$sum:1}}}

var etapas = [q1,q2]


db.genres.aggregate(etapas)

But, with this code, I only get in 'q1', the variable 'leap', all false conditionals. So, I do not know how to get the year when the logical operator is true or false. Even more, I want to count all the leap years of the documents I have been given before.

The expect output for the documents before is this:

{
    "_id": leap year
    "count": 3
}

How can I do that? How can I type when I've got a false result?

Thanks so much for your attention in this problem. Whatever ask you need, do it without any problem.


Solution

  • To check if a number is divisible by another, you need to see if the remainder is 0 using $mod, such as:

    db.collection.aggregate([
      {$project: {
          leap: {
            "$and": [
              {"$eq": [{"$mod": ["$year",4]}, 0]},
              {"$or": [
                  {"$ne": [{"$mod": ["$year", 100]}, 0]},
                  {"$eq": [{"$mod": ["$year", 400]}, 0] }
              ]}
            ]
          }
      }},
      {$group: {
          "_id": "$leap",
          "total": {$sum: 1}
      }}
    ])
    

    Playground