Using the $pull operator to remove an object via a nested field from an array in DocumentDB?

0

I have one entry in my Data collection and is as follows:

{
    "data": [
        {
            "key1": {
                "name": "test"
            }
        },
        {
            "key1": {
                "name": "test2"
            }
        }
    ]
}

I would like to remove the object where key1.name: 'test2' from the data array.

I have tried the following:

db.Data.updateOne({}, { $pull: { 'data': { 'key1.name': 'test2' } } })

This works fine in a container instance of mongodb:5.

But in a DocumentDB with engine version 5.0, it does not work and returns MongoServerError: Dotted field name is not valid for storage.

Is there any way for me to use the $pull operator in a DocumentDB where I'm targeting an object via a nested field?

If the $pull operator is not usable for this scenario, what other options do I have? I may have hundreds of documents in the Data collection, and would like to capability of pulling a specific object out of the data property of multiple documents without making hundreds of db calls

Ken
asked a month ago85 views
1 Answer
0

In Amazon DocumentDB, which is compatible with MongoDB 3.6, certain operations or syntax might behave differently compared to a native MongoDB instance. In this case, the error "Dotted field name is not valid for storage" suggests that DocumentDB doesn't support the dotted field name used in your query.

To work around this limitation, you can use the update() method with an appropriate query to achieve the desired result. Here's how you can do it:

db.Data.update(
  { },
  { $pull: { 'data': { 'key1.name': 'test2' } } },
  { multi: true }
)

This will remove the object where 'key1.name' is 'test2' from the data array in all documents in the Data collection.

The { multi: true } option ensures that the update operation affects multiple documents. However, keep in mind that the update() method with multi-update functionality is not as atomic as update operations on a single document. Ensure that your application can handle potential edge cases or concurrency issues that might arise during multi-document updates.

If you have a very large number of documents and performance is a concern, you might consider running the update operation in batches to avoid overwhelming the database server. You can achieve this by using a combination of query conditions and limits to process documents in manageable chunks.

// Process documents in batches of 100
let batchSize = 100;
let offset = 0;

while (true) {
  let result = db.Data.update(
    { },
    { $pull: { 'data': { 'key1.name': 'test2' } } },
    { multi: true, limit: batchSize, skip: offset }
  );

  if (result.nModified === 0) {
    // No more documents to update
    break;
  }

  offset += batchSize;
}

This approach iterates over the documents in the collection, applying the $pull operation in batches until all matching documents have been processed.

Remember to test any updates thoroughly in a development or staging environment before applying them to production data. Additionally, ensure that your application code gracefully handles any errors or edge cases that may arise during the update process.

profile picture
EXPERT
answered a month ago
  • Thank you for the response Giovanni.

    Unfortunately with the suggested solution, I still get the same error:

    db.Data.update({ }, { $pull: { 'data': { 'key1.name': 'test2' } } }, { multi: true })
    MongoServerError: Dotted field name is not valid for storage
    

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions