Search code examples
mongodbgroupingaggregation

MongoDB distinct with grouping


I am brand new in the mongo world. To the degree where I cannot really formulate my questions properly. But here goes... So here is my best attempt...

db.t2.insertOne( { animal: "cat", action: "meow"});
db.t2.insertOne( { animal: "cat", action: "stalk"});
db.t2.insertOne( { animal: "cat", action: "claw"});
db.t2.insertOne( { animal: "dog", action: "woof"});
db.t2.insertOne( { animal: "dog", action: "beg"});
db.t2.insertOne( { animal: "fish", action: "swim"});

The data is pretty flat, right?

db.t2.find();
{ _id: ObjectId("61142a398f4cfec27b46e89d"),
  animal: 'cat',
  action: 'meow' }
{ _id: ObjectId("61142a438f4cfec27b46e89e"),
  animal: 'cat',
  action: 'stalk' }
{ _id: ObjectId("61142a4a8f4cfec27b46e89f"),
  animal: 'cat',
  action: 'claw' }
{ _id: ObjectId("61142a7e8f4cfec27b46e8a0"),
  animal: 'dog',
  action: 'woof' }
{ _id: ObjectId("61142a838f4cfec27b46e8a1"),
  animal: 'dog',
  action: 'beg' }
{ _id: ObjectId("61142a918f4cfec27b46e8a2"),
  animal: 'fish',
  action: 'swim' }

I'm looking for a way to query the data more compressed. Something like...

[{
"animal":"cat",
"action":["meow", "stalk", "claw"]
},
"animal":"dog",
"action":["woof", "beg"]
},
"animal":"fish",
"action":["swim"]
}]

Solution

  • You can group them

    db.collection.aggregate([
      {
        "$group": {
          "_id": "$animal",
          "actions": {
            "$push": "$action"
          }
        }
      },
      {
        "$project": {
          "_id": 0,
          "animal": "$_id",
          "actions": 1
        }
      }
    ])
    

    Run code here

    If you want to save the data in the new form, you can do the above pipeline, and use an $out stage to create a new collection, with the new schema.