YulePale
YulePale

Reputation: 7736

How to alter an object in an array depending on a value in another object in another array in mongodb aggregation

let selections = [
      {
        _id: "5fb38d2dc79265e75f205094",
        questionId: "5fb04e0620abf8e5d9a15ced",
        selection: 'maybe'
      },
]

let questions= [
      {
        _id: "5fb04e0620abf8e5d9a15ced",
        selections: {
          yes: {
            marks: 1
          },
          maybe: {
            marks: 2
          },
          no: {
            marks: 3
          }
        },
      }
]

let newQuestions = questions.map(question=>{
  return selections.map(selection=>{
    if(question._id == selection.questionId){
        question.selections[selection.selection].selected = true;
        return question
    }
  })
})

The code above returns the output below.

[
      {
        _id: "5fb04e0620abf8e5d9a15ced",
        selections: {
          yes: {
            marks: 1
          },
          maybe: {
            marks: 2,
            selected: true // this is added
          },
          no: {
            marks: 3
          }
        },
      }
]

How can I achieve the same using mongodb aggregation? I have the aggregation code that results to the two arrays but I am stuck in trying to achieve what I have demonstrated with the code above.

Upvotes: 0

Views: 61

Answers (1)

turivishal
turivishal

Reputation: 36144

You can try,

  • $lookup to join selections collection
  • $unwind to deconstruct selections array and make object
  • $addFields to update selections array, $map to iterate loop of selections object after converting to array using $objectToArray, return k (key) and v (value) check condition if selection name is match then return selected: true otherwise not, $mergeObjects to merge current available objects with new added field, $arrayToObject to convert array back to the object format
  • remove selection field that is no longer needed
db.questions.aggregate([
  {
    $lookup: {
      from: "selections",
      localField: "_id",
      foreignField: "questionId",
      as: "selection"
    }
  },
  {
    $unwind: {
      path: "$selection",
      preserveNullAndEmptyArrays: true
    }
  },
  {
    $addFields: {
      selection: "$$REMOVE",
      selections: {
        $arrayToObject: [
          {
            $map: {
              input: { $objectToArray: "$selections" },
              in: {
                k: "$$this.k",
                v: {
                  $mergeObjects: [
                    "$$this.v",
                    {
                      $cond: [
                        { $eq: ["$$this.k", "$selection.selection"] },
                        { selected: true },
                        {}
                      ]
                    }
                  ]
                }
              }
            }
          }
        ]
      }
    }
  }
])

Playground

Upvotes: 1

Related Questions