0

I have such document structure:

{
  favourite_shops: [
    {
      shop_id: "5961352278cba91cc6a6e8cc",
      time: "2017-07-11T14:43:35.465Z"
    },
    {
      shop_id: "5964e446c15c760f9b646d99",
      time: "2017-07-11T14:44:40.429Z"
    },
    {
      shop_id: "5964e446c15c760f9b646d98",
      time: "2017-07-11T14:44:50.988Z"
    }
  ]
}

How can I transform this to something like this:

{
  favourite_shops: [
    "5961352278cba91cc6a6e8cc",
    "5964e446c15c760f9b646d99",
    "5964e446c15c760f9b646d98" 
  ]
}
8
  • @Veeram no its not working, it is not doing any tranformation. Commented Jul 11, 2017 at 17:25
  • do you want the result as query response or trying to modify after you get the response. Commented Jul 11, 2017 at 19:07
  • Sorry I meant db.collectonname.aggregate({$project:{"favourite_shops":"$favourite_shops.shop_id"}}); Commented Jul 11, 2017 at 19:57
  • @pe got thrayagupd I want it as query response and I have resolved my problem Commented Jul 12, 2017 at 8:47
  • @Veeram {$project:{"favourite_shops":"$fa‌​vourite_shops.shop_i‌​d"} only shows product id of fiest sub array . It does not show ids of all array elemenst. Commented Jul 12, 2017 at 15:18

2 Answers 2

1

You can $map on the array itself and get only the fields you need. (This is done within the query itself not after you receive the documents)

example.

given documents;

> db.Shopping.find().pretty()
{
    "_id" : ObjectId("59651ce38828356e1a39fde9"),
    "favourite_shops" : [
        {
            "shop_id" : "5961352278cba91cc6a6e8cc",
            "time" : "2017-07-11T14:43:35.465Z"
        },
        {
            "shop_id" : "5964e446c15c760f9b646d99",
            "time" : "2017-07-11T14:44:40.429Z"
        },
        {
            "shop_id" : "5964e446c15c760f9b646d98",
            "time" : "2017-07-11T14:44:50.988Z"
        }
    ]
}
{
    "_id" : ObjectId("59665cf3d8145b41e5d2f5da"),
    "favourite_shops" : [
        {
            "shop_id" : "2222",
            "time" : "2017-07-11T14:43:35.465Z"
        },
        {
            "shop_id" : "4444",
            "time" : "2017-07-11T14:44:40.429Z"
        },
        {
            "shop_id" : "6666",
            "time" : "2017-07-11T14:44:50.988Z"
        }
    ]
}

$map on favourite_shops array ({$match} block is optional, you can remove if you want shopping id for all documents)

> db.Shopping.aggregate([[
  {
    "$match": {
      "_id": ObjectId("59651ce38828356e1a39fde9")
    }
  },
  {
    "$project": {
      "my_favourite_shops": {
        "$map": {
          "input": "$favourite_shops",
          "as": "each_shop",
          "in": "$$each_shop.shop_id"
        }
      }
    }
  }
]).pretty()
{
    "_id" : ObjectId("59651ce38828356e1a39fde9"),
    "my_favourite_shops" : [
        "5961352278cba91cc6a6e8cc",
        "5964e446c15c760f9b646d99",
        "5964e446c15c760f9b646d98"
    ]
}

And, with mongodb 3.4.4, I simply could $project on nested field,

db.Shopping.aggregate([{"$project": {"my_favourite_shops": "$favourite_shops.shop_id"}}]).pretty()
{
    "_id" : ObjectId("59651ce38828356e1a39fde9"),
    "my_favourite_shops" : [
        "5961352278cba91cc6a6e8cc",
        "5964e446c15c760f9b646d99",
        "5964e446c15c760f9b646d98"
    ]
}
{
    "_id" : ObjectId("59665cf3d8145b41e5d2f5da"),
    "my_favourite_shops" : [
        "2222",
        "4444",
        "6666"
    ]
}
Sign up to request clarification or add additional context in comments.

3 Comments

You don't need $map for this in anything above MongoDB 3.0. Simply { "$project": "$my_favourite_shops.shop_id" } does the same thing, and is essentially a shortcut for $map with a single property.
@NeilLunn {$project:{"favourite_shops":"$fa‌​vourite_shops.shop_i‌​d"} only shows one product id. But I need to get all product ids of all array element.
thanks @NeilLunn. $project on nested field works properly in mongo 3.4.4. I updated the answer
1

Assuming we have such data structure:

const data = {
  favourite_shops: [
    {
      shop_id: "5961352278cba91cc6a6e8cc",
      time: "2017-07-11T14:43:35.465Z"
    },
    {
      shop_id: "5964e446c15c760f9b646d99",
      time: "2017-07-11T14:44:40.429Z"
    },
    {
      shop_id: "5964e446c15c760f9b646d98",
      time: "2017-07-11T14:44:50.988Z"
    }
  ]
};

Just a bit of ES6 magic:

const result = {
  favourite_shops: []
};

data.favourite_shops.forEach(el => result.favourite_shops.push(el.shop_id));

Second elegant approach:

const result = {
  favourite_shops: data.favourite_shops.map(el => el.shop_id)
};

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.