Search code examples
arraysmongodbaggregation

Problemm using concat in array mongodb


i have 3 tables

1) Actor: actor_id, first_name, last_name 
2) Film: film_id, title
3) Film_Actor: film_id, actor_id

Example document:

_id
:
60aedac769985522a024daca
actor_id
:
"1"
first_name
:
"Penelope"
last_name
:
"Guiness"

I wanto to result not only first_name, but last_name too. I'm facing problem with using concat in $group function. my FULLY codes:

    db.film.aggregate([
  {
    $lookup: {
      from: "film_actor",
      localField: "film_id",
      foreignField: "film_id",
      as: "film_actor"
    }
  },
  {
    $lookup: {
      from: "actor",
      localField: "film_actor.actor_id", 
      foreignField: "actor_id",
      as: "actor"
    }
  },
  {
    $group: {
      _id: "$film_id",
      title: {"$first":"$title"},
      name: {$push: "$actor.first_name"}
                }
  }
]);

Error report:

$concat only supports strings, not array

desired output:

id:"207"
title:"Dangerous Uptown"
name:Array
0:"Penelope Guiness"
1:"Mary Watson"
2:"Ralph Holts"
3:"Spencer Dani"

Solution

  • What you have done is appreciated, I've done some changes in your code

    • $lookup to join collections. I have started form Flim collection
    • $unwind to deconstruct the array
    • $group to reconstruct the array that we already deconstructed, this will
    • Since we have nested array we need to use $map to loop over them to collect the first name and lastname
    • The above stage will end up with again nested array, so we use $reduce to loop again and remove inner arrays using $setUnion

    remove some duplicate entries, depends on your requirements

    Here is the code

    db.Film.aggregate([
      {
        $lookup: {
          from: "Film_Actor",
          localField: "film_id",
          foreignField: "film_id",
          as: "join_flim"
        }
      },
      { "$unwind": "$join_flim" },
      {
        $lookup: {
          from: "Actor",
          localField: "join_flim.actor_id",
          foreignField: "actor_id",
          as: "join_flim.join_actor"
        }
      },
      {
        $group: {
          _id: "$_id",
          title: { $first: "$title" },
          join_flim: { $push: "$join_flim" }
        }
      },
      {
        "$project": {
          title: 1,
          actornames: {
            $map: {
              input: "$join_flim",
              as: "f",
              in: {
                $map: {
                  input: "$$f.join_actor",
                  as: "a",
                  in: {
                    $concat: [ "$$a.first_name", " ", "$$a.last_name" ]
                  }
                }
              }
            }
          }
        }
      },
      {
        "$project": {
          title: 1,
          actornames: {
            "$reduce": {
              "input": "$actornames",
              "initialValue": [],
              "in": {
                "$setUnion": [ "$$this", "$$value" ]
              }
            }
          }
        }
      }
    ])
    

    Working Mongo playground