Array Operation in MongoDB

ChunTing Wu - Jan 17 '22 - - Dev Community

MongoDB is a document-based database, and a document is JSON-like format. Therefore, MongoDB can store various data structures. Moreover, in order to manage those documents, MongoDB provides a powerful ubiquitous language to operate documents.

Here comes a question. We usually perform CRUD on documents, however, do you know how to update the element in a list from certain documents? This article is my experiment of array operations.

The original collections is given as follows:

{ _id: ObjectId("61bb0d7cf08a56308c62110b"),
  prop: [ { a: 1, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dbaf08a56308c62110c"),
  prop: [ { a: 1, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dcaf08a56308c62110d"),
  prop: [ { a: 3, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0fcef08a56308c62110e"),
  prop: [ { a: 1, b: false } ] }
Enter fullscreen mode Exit fullscreen mode

Update a key of elements in an array

We have an array, prop, with elements, and those elements contains a and b are integer and boolean respectively. What we want to do is update b to false if a is equal to 1.

The command is: db.test.updateMany({"prop.a": 1}, {$set: {"prop.$.b": false}}). There is a dollar sign representing the result set from filtering. So, prop.$.b means all b with a is 1.

After executing the command, the collection would be:

{ _id: ObjectId("61bb0d7cf08a56308c62110b"),
  prop: [ { a: 1, b: false }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dbaf08a56308c62110c"),
  prop: [ { a: 1, b: false }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dcaf08a56308c62110d"),
  prop: [ { a: 3, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0fcef08a56308c62110e"),
  prop: [ { a: 1, b: false } ] }
Enter fullscreen mode Exit fullscreen mode

Remove a key of elements in an array

We can $set a key; on the other hand, we can remove a key either. The command is like the $set one.

db.test.updateMany({"prop.a": 1}, {$unset: {"prop.$.b": ""}})

When we want to $unset a key, the syntax is {key: ""}, thus, {$unset: {"prop.$.b": ""} is as expected.

Finally, the collection would be:

{ _id: ObjectId("61bb0d7cf08a56308c62110b"),
  prop: [ { a: 1 }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dbaf08a56308c62110c"),
  prop: [ { a: 1 }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0dcaf08a56308c62110d"),
  prop: [ { a: 3, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0fcef08a56308c62110e"),
  prop: [ { a: 1 } ] }
Enter fullscreen mode Exit fullscreen mode

Remove a key of certain elements in an array

Furthermore, if we want to remove b when b is true rather than all b. How can we do?

The solution is: db.test.updateMany({"prop.a": 1}, {$unset: {"prop.$[elem].b": ""}}, {arrayFilters: [{"elem.b": true}]}).

We are using arrayFilters to match the specific elements and indicating those elements to the $unset criteria. Then, the collection would become:

{ _id: ObjectId("61bb0d7cf08a56308c62110b"),
  prop: [ { a: 1 }, { a: 2 } ] }
{ _id: ObjectId("61bb0dbaf08a56308c62110c"),
  prop: [ { a: 1 }, { a: 2 } ] }
{ _id: ObjectId("61bb0dcaf08a56308c62110d"),
  prop: [ { a: 3, b: true }, { a: 2, b: true } ] }
{ _id: ObjectId("61bb0fcef08a56308c62110e"),
  prop: [ { a: 1, b: false } ] }
Enter fullscreen mode Exit fullscreen mode

Although we can use filter like {a: 1, b: true} to leverage the dollar sign operations, arrayFilters provides more possibilities to achieve more complex user scenarios. You can try to skill it.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player