title: MongoDB how we can group data by field value
body: <p>I have the following query, what I want is to have a combined group of custom group field names, with field value.</p>
  
  <pre><code>db.getCollection('mycollection').aggregate([
    {"$match":{
       "expireDate":{"$gte":"2018-02-06T00:00:00.000Z"},
       "publishDate":{"$lte":"2018-02-06T00:00:00.000Z"},
       "isPublished":true,"isDrafted":false,
       "deletedAt":{"$eq":null},"deleted":false
    }},
    {"$group":{
       "twentyFourHourAgo":{
          "$sum":{
             "$cond":[
               {"$gt":["$publishDate","2018-02-04T08:48:16.892Z"]},1,0
             ]
          }
        },
        "fortyEightHourAgo":{
          "$sum":{
              "$cond":[
                 {"$gt":["$publishDate","2018-02-01T08:48:16.892Z"]},1,0
              ]
          }
        },
        "thirtyDaysAgo":{
           "$sum":{
              "$cond":[
                 {"$gt":["$publishDate","2017-12-31T08:48:16.892Z"]},1,0
              ]
           }
        },
        "_id":{
          "position":{"$ifNull":["$position","Unknown"]},
          "workType":{"$ifNull":["$workType","Unknown"]},
          "functionalArea":{"$ifNull":["$functionalArea","Unknown"]},
          "minimumEducation":{"$ifNull":["$minimumEducation","Unknown"]},
          "gender":{"$ifNull":["$gender","Unknown"]},
          "contractType":{"$ifNull":["$contractType","Unknown"]},
          "locations":{"$ifNull":["$locations","Unknown"]},
          "requiredLanguages":{"$ifNull":["$requiredLanguages","Unknown"]},
          "company":{"$ifNull":["$company.name","Unknown"]}},"count":{"$sum":1}
       }
   },
   {"$group":{
       "_id":null,
       "twentyFourHourAgo":{
          "$sum":"twentyFourHourAgo"
       },
       "fortyEightHourAgo":{
          "$sum":"$fortyEightHourAgo"
       },
       "thirtyDaysAgo":{
          "$sum":"$thirtyDaysAgo"
       },
       "position":{"$addToSet":{"Name":"$_id.position","Count":"$count"}},
       "workType":{"$addToSet":{"Name":"$_id.workType","Count":"$count"}},
       "functionalArea":{
          "$addToSet":{"Name":"$_id.functionalArea","Count":"$count"}
       },
       "minimumEducation":{
          "$addToSet":{"Name":"$_id.minimumEducation","Count":"$count"}
       },
       "gender":{"$addToSet":{"Name":"$_id.gender","Count":"$count"}},"contractType":{"$addToSet":{"Name":"$_id.contractType","Count":"$count"}},"locations":{"$addToSet":{"Name":"$_id.locations","Count":"$count"}},"requiredLanguages":{"$addToSet":{"Name":"$_id.requiredLanguages","Count":"$count"}},"company":{"$addToSet":{"Name":"$_id.company","Count":"$count"}}}}]  
  )
  </code></pre>
  
  <p>my document inside collection schema is like:</p>
  
  <pre><code>/* 1 */
  {
      "_id" : ObjectId("59e4540bf14f1607b90ffb81"),
      "vacancyNumber" : "1",
      "position" : "Software Tester",
      "publishDate" : ISODate("2018-01-02T00:00:00.000Z"),
      "expireDate" : ISODate("2018-05-29T00:00:00.000Z"),
      "yearsOfExperience" : 40,
      "minimumEducation" : "Doctorate",
      "functionalArea" : "Education",
      "company" : {
          "id" : ObjectId("59e453fbf14f1607b90ffb80"),
          "name" : "First Company",
          "profile" : "profile",
          "logo" : {
              "container" : "companyFiles",
              "name" : "abbbff58cd3fda2c59ab2ee620ea5aa0",
              "mime" : ".png",
              "size" : 5806
          }
      },
      "durations" : {
          "years" : 3,
          "months" : 4
      },
      "probationPeriod" : {
          "duration" : 34,
          "unit" : "month"
      },
      "salary" : {
          "minSalary" : 1000,
          "maxSalary" : 2000,
          "currency" : "USD",
          "period" : "monthly",
          "isNegotiable" : true
      },
      "locations" : [ 
          "Germany", 
          "Itly", 
          "Iran"
      ],
      "canApplyOnline" : true,
      "skills" : [ 
          "Skill1", 
          "Skill2", 
          "Skill3", 
          "Skill4"
      ],
      "requiredLanguages" : [ 
          "Arabic", 
          "English", 
          "Russian", 
          "Dari", 
          "French"
      ],
      "keywords" : [ 
          "Key1", 
          "Key2"
      ],
      "deleted" : false,
      "deletedAt" : null,
      "isDrafted" : false,
      "isPublished" : true,
      "requiresTravel" : true,
      "gender" : "male",
      "nationalities" : [ 
          "afghan"
      ],
      "workType" : "Full Time",
      "contractType" : "Permanent",
  }
  
  /* 2 */
  {
      "_id" : ObjectId("59f9402e05d04ebe5653d98f"),
      "vacancyNumber" : "1",
      "position" : "Software Engineer",
      "publishDate" : ISODate("2018-01-03T00:00:00.000Z"),
      "expireDate" : ISODate("2018-11-10T00:00:00.000Z"),
      "yearsOfExperience" : 40,
      "minimumEducation" : "Doctorate",
      "functionalArea" : "Education",
      "company" : {
          "id" : ObjectId("59e453fbf14f1607b90ffb80"),
          "name" : "First Company",
          "profile" : "profile",
          "logo" : {
              "container" : "logo container",
              "name" : "logo name",
              "mime" : "logo mime type",
              "size" : 1
          }
      },    
      "durations" : {
          "years" : 3,
          "months" : 4
      },
      "probationPeriod" : {
          "duration" : 34,
          "unit" : "month"
      },
      "salary" : {
          "minSalary" : 1000,
          "maxSalary" : 2000,
          "currency" : "USD",
          "period" : "monthly",
          "isNegotiable" : true
      },
      "locations" : [ 
          "Afghanistan", 
          "Itly", 
          "Iran"
      ],
      "skills" : [ 
          "Skill1", 
          "Another Skill"
      ],
      "requiredLanguages" : [ 
          "Arabic", 
          "English", 
          "Russian", 
          "Dari", 
          "French"
      ],
      "keywords" : [ 
          "Keyword", 
          "Key1"
      ],
      "deleted" : false,
      "deletedAt" : null,
      "isDrafted" : false,
      "isPublished" : true,
      "gender" : "male",
      "nationalities" : [ 
          "afghan", 
          "iranian"
      ],
      "workType" : "Full Time",
      "contractType" : "Short-Term",
  }
  
  /* 3 */
  {
      "_id" : ObjectId("5a03235234f7504f13970abd"),
      "vacancyNumber" : "1",
      "position" : "Software Tester",
      "publishDate" : ISODate("2017-10-10T00:00:00.000Z"),
      "expireDate" : ISODate("2018-11-25T00:00:00.000Z"),
      "yearsOfExperience" : 40,
      "minimumEducation" : "Doctorate",
      "functionalArea" : "IT Software",
      "company" : {
          "id" : ObjectId("59e453fbf14f1607b90ffb80"),
          "name" : "My First Company",
          "profile" : "profile",
          "logo" : {
              "container" : "logo container",
              "name" : "logo name",
              "mime" : "logo mime type",
              "size" : 1
          }
      },
      "durations" : {
          "years" : 3,
          "months" : 4
      },
      "probationPeriod" : {
          "duration" : 34,
          "unit" : "month"
      },
      "salary" : {
          "minSalary" : 1000,
          "maxSalary" : 2000,
          "currency" : "USD",
          "period" : "monthly",
          "isNegotiable" : true
      },
      "locations" : [ 
          "Germany", 
          "Itly", 
          "Iran"
      ],
      "skills" : [ 
          "Skill1", 
          "Test Skill"
      ],
      "requiredLanguages" : [ 
          "Arabic", 
          "English", 
          "Russian", 
          "Dari", 
          "French"
      ],
      "keywords" : [ 
          "Test Key", 
          "Keyword"
      ],
      "deleted" : false,
      "deletedAt" : null,
      "isDrafted" : false,
      "isPublished" : true,
      "gender" : "female",
      "nationalities" : [ 
          "afghan"
      ],
      "workType" : "Part Time",
      "contractType" : "Permanent",
  }
  </code></pre>
  
  <p>Now I want to count the group of data by my custom expression check 'twentyFourHourAgo, fortyEightHourAgo, thirtyDaysAgo', and also by the value of a field (<code>functionalArea, position, locations, keywords, workType</code>).</p>
  
  <p>My current query result is </p>
  
  <pre><code>{
      "_id" : null,
      "twentyFourHourAgo" : 0,
      "fortyEightHourAgo" : 0.0,
      "thirtyDaysAgo" : 2.0,
      "position" : [ 
          {
              "Name" : "Software Engineer",
              "Count" : 1.0
          }, 
          {
              "Name" : "Software Tester",
              "Count" : 1.0
          }
      ],
      "workType" : [ 
          {
              "Name" : "Full Time",
              "Count" : 1.0
          }, 
          {
              "Name" : "Part Time",
              "Count" : 1.0
          }
      ],
      "functionalArea" : [ 
          {
              "Name" : "Education",
              "Count" : 1.0
          }, 
          {
              "Name" : "IT Software",
              "Count" : 1.0
          }
      ],
      "minimumEducation" : [ 
          {
              "Name" : "Doctorate",
              "Count" : 1.0
          }
      ],
      "gender" : [ 
          {
              "Name" : "male",
              "Count" : 1.0
          }, 
          {
              "Name" : "female",
              "Count" : 1.0
          }
      ],
      "contractType" : [ 
          {
              "Name" : "Short-Term",
              "Count" : 1.0
          }, 
          {
              "Name" : "Permanent",
              "Count" : 1.0
          }
      ],
      "locations" : [ 
          {
              "Name" : [ 
                  "Afghanistan", 
                  "Itly", 
                  "Iran"
              ],
              "Count" : 1.0
          }, 
          {
              "Name" : [ 
                  "Germany", 
                  "Itly", 
                  "Iran"
              ],
              "Count" : 1.0
          }
      ],
      "requiredLanguages" : [ 
          {
              "Name" : [ 
                  "Arabic", 
                  "English", 
                  "Russian", 
                  "Dari", 
                  "French"
              ],
              "Count" : 1.0
          }
      ],
      "company" : [ 
          {
              "Name" : "First Company",
              "Count" : 1.0
          }, 
          {
              "Name" : "My First Company",
              "Count" : 1.0
          }
      ]
  }
  </code></pre>
  
  <p>As you see, I have three document that has following properties:</p>
  
  <ol>
  <li>Two document that has the same position <code>Software Tester</code>, but query return <code>1 Software Tester</code> (It means if I have multiple documents that have some common values in specific columns, their count result is wrong). The same problem exists for other fields 'contractType, workType, etc...'.</li>
  <li><p>In array-type fields such as <code>locations</code>, my first document has <code>Germany, Italy, Iran</code> values in <code>locations</code> array, my second document has <code>Afghanistan, Italy, Iran</code>, and my third document has <code>Germany, Italy, Iran</code>. But query result is like this:</p>
  
  <pre><code>"locations" : [ 
    {
      "Name" : [ 
        "Afghanistan", 
        "Itly", 
        "Iran"
      ],
      "Count" : 1.0
    }, 
    {
      "Name" : [ 
        "Germany", 
        "Itly", 
        "Iran"
      ],
      "Count" : 1.0
    }
   ],
  </code></pre></li>
  </ol>
  
  <p>This should be like: <code>Germany =&gt; 2, Italy,Iran =&gt; 3, and Afghanistan =&gt; 1</code>
  The same problem exists for other array type fields.</p>