Home > OS >  Convert array of objects to array of strings in mongodb
Convert array of objects to array of strings in mongodb

Time:12-13

I am looking at the following documentation.

The following inserts documents into a collection classes.

db.classes.insertMany( [
   { _id: 1, title: "Reading is ...", enrollmentlist: [ "giraffe2", "pandabear", "artie" ], days: ["M", "W", "F"] },
   { _id: 2, title: "But Writing ...", enrollmentlist: [ "giraffe1", "artie" ], days: ["T", "F"] }
] )

And the members collection:

db.members.insertMany( [
   { _id: 1, name: "artie", joined: new Date("2016-05-01"), status: "A" },
   { _id: 2, name: "giraffe", joined: new Date("2017-05-01"), status: "D" },
   { _id: 3, name: "giraffe1", joined: new Date("2017-10-01"), status: "A" },
   { _id: 4, name: "panda", joined: new Date("2018-10-11"), status: "A" },
   { _id: 5, name: "pandabear", joined: new Date("2018-12-01"), status: "A" },
   { _id: 6, name: "giraffe2", joined: new Date("2018-12-01"), status: "D" }
] )

They use the following aggregation to join the two collections on the array field, enrollmentlist.

db.classes.aggregate( [
   {
      $lookup:
         {
            from: "members",
            localField: "enrollmentlist",
            foreignField: "name",
            as: "enrollee_info"
        }
   }
] )

Which returns the following:

{
   "_id" : 1,
   "title" : "Reading is ...",
   "enrollmentlist" : [ "giraffe2", "pandabear", "artie" ],
   "days" : [ "M", "W", "F" ],
   "enrollee_info" : [
      { "_id" : 1, "name" : "artie", "joined" : ISODate("2016-05-01T00:00:00Z"), "status" : "A" },
      { "_id" : 5, "name" : "pandabear", "joined" : ISODate("2018-12-01T00:00:00Z"), "status" : "A" },
      { "_id" : 6, "name" : "giraffe2", "joined" : ISODate("2018-12-01T00:00:00Z"), "status" : "D" }
   ]
}
{
   "_id" : 2,
   "title" : "But Writing ...",
   "enrollmentlist" : [ "giraffe1", "artie" ],
   "days" : [ "T", "F" ],
   "enrollee_info" : [
      { "_id" : 1, "name" : "artie", "joined" : ISODate("2016-05-01T00:00:00Z"), "status" : "A" },
      { "_id" : 3, "name" : "giraffe1", "joined" : ISODate("2017-10-01T00:00:00Z"), "status" : "A" }
   ]
}

How can I reduce enrolle_info just to be an array of strings with all of the names?

This is the result I am after:

{
   "_id" : 1,
   "title" : "Reading is ...",
   "enrollmentlist" : [ "giraffe2", "pandabear", "artie" ],
   "days" : [ "M", "W", "F" ],
   "enrollee_info" : [
      "artie",
      "pandabear"
      "giraffe2"
   ]
}
{
   "_id" : 2,
   "title" : "But Writing ...",
   "enrollmentlist" : [ "giraffe1", "artie" ],
   "days" : [ "T", "F" ],
   "enrollee_info" : [
      "artie",
      "giraffe1"
   ]
}

I have also looked into using multiple joins by introducing the pipeline field inside the $lookup operation. I am able to use a $project to get an array just with {"name": "example"} but I am not sure how to remove the "name". I have tried using an {"$unwind": "$enrollee_info.name"} but that does not give me what I want. Do I need to introduce another stage to my aggregation pipeline after I do the join?

CodePudding user response:

It seems that I was over complicating this. I was able to achieve my desired result by doing the following:

db.classes.aggregate( [
   {
      $lookup:
         {
            from: "members",
            localField: "enrollmentlist",
            foreignField: "name",
            as: "enrollee_info"
         }
   },
   {
      $project:
          {
              "_id": 1,
              "title": 1,
              "days": 1,
              "enrollee_names": "$enrollee_info.name"
          }
   } 
] )

Result:

[
    {
        "id": 1,
        "title": "Reading is ...",
        "days": [
            "M",
            "W",
            "F"
        ],
        "names": [
            "artie",
            "pandabear",
            "giraffe2"
        ]
    },
    {
        "id": 2,
        "title": "But Writing ...",
        "days": [
            "T",
            "F"
        ],
        "names": [
            "artie",
            "giraffe1"
        ]
    }
]
  • Related