Home > Enterprise >  How to $unset a embedded field MongoDB?
How to $unset a embedded field MongoDB?

Time:10-19

Here my document for example:

[{
  _id: ObjectId("609391f436e519039a634311"),
  name: "Class A",
  numOfStudents: 10,
  students: [{
    name: "Student A",
    age: 10,
  }, {
    name: "Student B",
    age: 10,
  }]
}]

I want to update some values of class and remove some informations of all students in class. So I am using $set and $unset in updateOne, like below:

db.class.updateOne({
  _id: ObjectId("609391f436e519039a634311")
}, {
  $set: { something: "Something for describe" },
  $unset: { "students.$[].age": "" }
})

But now, I want $set a value to something by value of another field, I have to convert above script to a pipeline like below:

db.class.updateOne({
  _id: ObjectId("609391f436e519039a634311")
}, [
  {
    $set: { something: "$name" },
  }, {
    $unset: [
      "students.$[].age"
    ]
  }
])

But it didn't work, it threw an Error: Invalid $unset :: caused by :: FieldPath field names may not start with '$'. Consider using $getField or $setField.

Please give me a suggestion for this.

CodePudding user response:

You can't use paths that we use in update operators in aggregation. When aggregate you can only use aggregate operators, ONLY exception is the match stage that you can use query operators also.

Query1

  • unset age

Test code here

update(
{"_id": ObjectId("609391f436e519039a634311")},
[{"$set": {"something": "$name"}},
 {"$unset": ["students.age"]}])

Query2

  • you can use the "$$REMOVE" system variable, if a field gets this value its removed
  • here is like setting all age fields to have value $$REMOVE so they are removed

Test code here

update(
{"_id": ObjectId("609391f436e519039a634311")},
[{"$set": {"something": "$name", "students.age": "$$REMOVE"}}])

Query3

  • from students we only keep the name (=> age is removed)
  • you have to write by hand all the fields you want to keep

Test code here

update(
{"_id": ObjectId("609391f436e519039a634311")},
[{"$set": {"something": "$name",
           "students": 
             {"$map": {"input": "$students", "in": {"name": "$$this.name"}}}}}])
  • Related