skip to Main Content

This is the data,

{
    "categories": [
        {
            "categoryId": "6492acddeea12078cfcd82d5",
            "status": 'ACTIVE'
        },
        {
            "categoryId": "64993726f5ac84a75d773c54",
                        "status": 'INACTIVE'        
        },
        {
            "categoryId": "64993cd88af1246627d1cf96",
            "status": 'ACTIVE'        
        },
        {
            "categoryId": "64993726f5ac84a75d773c84",
            "status": 'INACTIVE'        
        },
        {
            "categoryId": "64993cd88af1246627d1cf66",
            "status": 'ACTIVE'        
        }
    ]
}

I have various categories with various statuses. I now want to filter each category and change each one’s status in the database.

Condition: I want to call the database just once to update the data.

I have tried this but it is not working.


{
    $filter: {
        input: "categories", //array of categories
        as: "cat",
        cond: { $eq: ["$$cat.categoryId", "$_id"] }
     }
}

any help would be greatly appreciated. Cheers!

2

Answers


  1. To update multiple objects in an array within a MongoDB document using a single MongoDB query, you can make use of the updateMany function along with the $set operator and the positional operator $[< identifier>]. Here’s an example query that updates the status of multiple categories in the given document:

    db.collection.updateMany(
      {},
      {
        $set: {
          "categories.$[elem].status": "NEW_STATUS"
        }
      },
      {
        arrayFilters: [
          {
            "elem.categoryId": {
              $in: ["64993726f5ac84a75d773c54", "64993726f5ac84a75d773c84"]
            }
          }
        ]
      }
    );
    

    In the above query, you need to replace collection with the actual name of your MongoDB collection. Also, replace "NEW_STATUS" with the desired status value you want to update the matching categories to. The "categoryId" values within the $in array determine which categories should be updated.

    This query uses an empty filter {} to match all documents in the collection. The $set operator updates the status field of the matched categories within the array. The arrayFilters option is used to specify the condition for filtering the elements of the categories array. In this case, it checks if the categoryId of the category matches any of the specified values.

    By executing this query, all matching categories will have their status field updated to the new value in a single operation.

    Login or Signup to reply.
  2. I’m assuming that your service uses a category array.

    First, since the categories array’s provided ids are of the string type, you must convert them to ObjectId() and set up a filter for your updateMany method.

    const categoryIds = categories.map(
        (obj) => {
          obj.categoryId = ObjectId(obj.categoryId);
          return obj.categoryId;
        }
      );
    
      const query = {
        _id: {
          $in: categoryIds,
        },
      };
    

    now prepare call your updateMany method with your prepared query filter.

    {
     yourMethod.updateMany(query, [
        {
          $set: {
            status: {
              $let: {
                vars: {
                  obj: {
                    $arrayElemAt: [
                      {
                        $filter: {
                          input: categories,
                          as: "cat",
                          cond: {
                            $eq: ["$$cat.categoryId", "$_id"],
                          },
                        },
                      },
                      0,
                    ],
                  },
                },
                in: "$$obj.status"
              },
            },
          },
        },
      ]);
    }
    

    the $set operator is used to update the value of a field in a document. It allows you to modify existing fields or add new fields to the document.

    the $let operator allows you to define variables within an aggregation pipeline. It’s useful when you need to compute values or perform operations that you want to reuse within the same pipeline stage.

    the $arrayElemAt operator is used to retrieve an element from an array based on its index position. The operator takes an array as input and returns the element at the specified index.

    the $filter operator is used to select a subset of elements from an array field in a document based on specific criteria. It is commonly used within the aggregation framework to perform complex queries and transformations on the data. The $filter operator takes an input array and an expression that defines the condition for filtering. The expression can use a variety of comparison operators, logical operators, and other MongoDB query operators to define the filter condition.

    the $eq operator is used to compare two values and check if they are equal. It is commonly used within queries, aggregations, and updates to perform equality checks.

    Visit the mongodb doc for additional information.

    I hope that you or someone else may find this useful.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search