1

I have the following documents in my collection:

{
  "archives" : [ 
    { "colour" : "red", "default" : true }, 
    { "colour" : "green", "default" : false }
  ]
}
{
  "archives" : [ 
    { "colour" : "yellow", "default" : true } 
  ] 
}

I want to project the colour value from the archive objects as follows:

{
  "archives" : [ "red", "green" ]
}
{
  "archives" : [ "yellow" ] 
}

My proposal

My best attempt at this has been this query:

db.test.find({}, {
    'archives': {
        '$map': {
            'input': '$archives', 
            'in': '$archives.colour'
         }
     }
})

But it's returning an array of arrays with redundant information, like so:

{ "archives" : [ [ "red", "green" ], [ "red", "green" ] ] }
{ "archives" : [ [ "yellow" ] ] }

So what would be the correct query to give the result I need, preferably on the database side, and as efficient as possible?

2 Answers 2

2

Why not simply this:

db.test.aggregate([
   { $set: { archives: "$archives.colour" } }
])

If you like to use $map, then is would be this one. You missed the $$this variable:

db.test.aggregate([
  {
    $set: {
      archives: {
        "$map": {
          "input": "$archives",
          "in": "$$this.colour"
        }
      }
    }
  }
])

or

db.test.aggregate([
  {
    $set: {
      archives: {
        "$map": {
          "input": "$archives.colour",
          "in": "$$this"
        }
      }
    }
  }
])
Sign up to request clarification or add additional context in comments.

Comments

2

You can use aggregation framework:

$unwind

$group

db.test.aggregate([
  {
    "$unwind": "$archives"
  },
  {
    "$group": {
      "_id": "$_id",
      "archives": {
        "$push": "$archives.colour"
      }
    }
  }
])

Playground

And if you don't want the _id in the output, you can exclude it by adding an additional $project stage:

db.test.aggregate([
  {
    "$unwind": "$archives"
  },
  {
    "$group": {
      "_id": "$_id",
      "archives": {
        "$push": "$archives.colour"
      }
    }
  },
  {
    "$project": {
      _id: 0
    }
  }
])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.