使用单个MongoDB查询更新多个元素

huangapple go评论113阅读模式
英文:

Update multiple element with single MongoDB query

问题

这是数据,

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

我有各种不同状态的分类。我现在想要筛选每个分类并在数据库中更改每个分类的状态。

条件:我希望只调用数据库一次来更新数据。

我尝试了以下代码,但它不起作用。

{
    $filter: {
        input: "categories", //分类数组
        as: "cat",
        cond: { $eq: ["$$cat.categoryId", "$_id"] }
    }
}

任何帮助将不胜感激。谢谢!

英文:

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!

答案1

得分: 1

我假设你的服务使用了一个类别数组。

首先,由于类别数组提供的ID是字符串类型的,你必须将它们转换为ObjectId()并为你的updateMany方法设置一个过滤器。

const categoryIds = categories.map(
    (obj) => {
      obj.categoryId = ObjectId(obj.categoryId);
      return obj.categoryId;
    }
  );

  const query = {
    _id: {
      $in: categoryIds,
    },
  };

现在准备使用你准备好的查询过滤器调用你的updateMany方法。

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

$set操作符用于更新文档中字段的值。它允许你修改现有字段或向文档中添加新字段。

$let操作符允许你在聚合管道内部定义变量。在需要在同一管道阶段内计算值或执行操作并希望在其中重用时非常有用。

$arrayElemAt操作符用于根据索引位置从数组中检索元素。该操作符接受一个数组作为输入,并返回指定索引处的元素。

$filter操作符用于根据特定条件从文档中的数组字段中选择子集。它通常在聚合框架内部用于执行复杂的查询和数据转换。$filter操作符接受一个输入数组和定义过滤条件的表达式。该表达式可以使用各种比较运算符、逻辑运算符和其他MongoDB查询操作符来定义过滤条件。

$eq操作符用于比较两个值并检查它们是否相等。它通常在查询、聚合和更新中用于执行相等性检查。

访问MongoDB文档以获取更多信息。

希望你或其他人能够找到这些信息有用。

英文:

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.

答案2

得分: 0

要使用单个MongoDB查询更新MongoDB文档中数组中的多个对象,您可以使用updateMany函数以及**$set运算符和位置运算符$[< identifier>]**。以下是一个更新给定文档中多个类别状态的示例查询:

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

在上面的查询中,您需要将collection替换为您的MongoDB集合的实际名称。还要将**"NEW_STATUS"替换为要将匹配的类别更新为的所需状态值。$in数组中的"categoryId"**值确定哪些类别应该进行更新。

此查询使用空过滤器{}来匹配集合中的所有文档。$set运算符更新数组中匹配类别的状态字段。arrayFilters选项用于指定筛选类别数组元素的条件。在这种情况下,它检查类别的categoryId是否与指定的任何值匹配。

通过执行此查询,所有匹配的类别将在单个操作中将其状态字段更新为新值。

英文:

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: {
      &quot;categories.$[elem].status&quot;: &quot;NEW_STATUS&quot;
    }
  },
  {
    arrayFilters: [
      {
        &quot;elem.categoryId&quot;: {
          $in: [&quot;64993726f5ac84a75d773c54&quot;, &quot;64993726f5ac84a75d773c84&quot;]
        }
      }
    ]
  }
);

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.

huangapple
  • 本文由 发表于 2023年7月13日 20:29:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76679397.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定