Search code examples
mongodbmongodb-queryaggregation-frameworkmongodb-aggregation

Mongodb concat not working in aggregation


In my query the concat keyword is not working, it return null.

Here is query:-

db.leads.aggregate([
{$project:{
    _id:0,
    status:1,
    stage:1,
    "todo.title":1,
    created:{
        day:{$substr:["$createdOn",8,2]},
        month:{$substr:["$createdOn",5,2]},
        year:{$substr:["$createdOn",0,4]}
        },
     myDate:{$concat:["$created.day","-","$created.month","-","$created.day"]}
         //----above $concat is not working-----//
         //--i want that `myDate` should be "12-09-2016"----//
    }
  }

])

Here is query output:-

{
    "stage" : "Prospect",
    "todo" : [],
    "status" : "OPEN",
    "created" : {
        "day" : "12",
        "month" : "09",
        "year" : "2016"
    },
    "myDate" : null

   //--here i want that `myDate` should be "12-09-2016"----//
}

createdOn field data store in mongodb as Date type i.e,

enter image description here


Solution

  • You don't necessarily need the $concat operator (i.e. if you're using MongoDB 3.0 and newer), the $dateToString operator does this for you already:

    db.leads.aggregate([
        {
            "$project": {           
                "status": 1,
                "stage": 1,
                "todo.title": 1,
                "created": {
                    "day": { "$dayOfMonth": "$createdOn" },
                    "month": { "$month": "$createdOn" },
                    "year": { "$year": "$createdOn" }
                },
                "myDate": { "$dateToString": { "format": "%Y-%m-%d", "date": "$createdOn" } }   
            }
        }
    ])
    

    If you are using MongoDB versions 2.6 or earlier which do not have support for the $dateToString operator then you need two $project pipeline stages. The first creates the created date field which then pipes the result to the next $project stage that creates myDate.

    The following example shows this approach:

    db.leads.aggregate([
        {
            "$project": {           
                "status": 1,
                "stage": 1,
                "todo.title": 1,
                "created": {
                    "day": { "$substr": ["$createdOn", 8, 2] },
                    "month": { "$substr": ["$createdOn", 5, 2] },
                    "year": { "$substr": ["$createdOn", 0, 4] }
                }   
            }
        },
        {
            "$project": {
                "_id": 0,
                "status": 1,
                "stage": 1,
                "todo": 1,
                "created": 1,
                "myDate": { 
                    "$concat": [
                        "$created.year", 
                        "-", 
                        "$created.month", 
                        "-", 
                        "$created.day"
                    ] 
                }       
            }
        }
    ])
    

    or rather as a single pipeline with expressions as the $concat arguments:

    db.leads.aggregate([
        {
            "$project": {
                "_id": 0,           
                "status": 1,
                "stage": 1,
                "todo.title": 1,
                "created": {
                    "day": { "$substr": ["$createdOn", 8, 2] },
                    "month": { "$substr": ["$createdOn", 5, 2] },
                    "year": { "$substr": ["$createdOn", 0, 4] }
                },
                "myDate": { 
                    "$concat": [
                        { "$substr": ["$createdOn", 0, 4] }, 
                        "-", 
                        { "$substr": ["$createdOn", 5, 2] }, 
                        "-", 
                        { "$substr": ["$createdOn", 8, 2] }
                    ] 
                }       
            }
        }
    ])