Docs 菜单
Docs 主页
/
数据库手册
/ /

使用MQL位置操作符更新文档中的数组元素

您可以将位置运算符与MongoDB查询语言 (MQL) 结合使用来 更新包含数组的文档,而无需替换大量或向数组追加内容。

本教程介绍了MongoDB中位置操作符的几个用例。

  • 安装 mongosh。

  • 连接到部署。

  • 使用 mongosh 将文档插入到默认test数据库的新集合中:

    db.employees.insertMany(
    [
    {
    _id: 'SF',
    engineering: [
    { name: 'Alice', email: 'missingEmail', salary: 100000 },
    { name: 'Bob', email: 'missingEmail', salary: 75000 }
    ],
    sales: [
    { name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 }
    ]
    },
    {
    _id: 'NYC',
    engineering: [
    { name: 'Dave', email: 'dave@mail.com', salary: 55000 },
    ],
    sales: [
    { name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 },
    { name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 }
    ]
    }
    ]
    );

以下示例展示了如何:

要仅更新大量中的第一个匹配项,请使用 $ 操作符。$ 操作符充当占位符,以更新第一个匹配的元素。

以下示例使用 updateOne() 方法以及 $$set 操作符将 engineering 大量中第一封具有值 missingEmail 的电子邮件更新为 alice@mail.com

1db.employees.updateOne(
2 { "engineering.email": "missingEmail" },
3 { "$set": { "engineering.$.email": "alice@mail.com" } }
4);

使用 find() 方法确认对爱丽丝电子邮件的更新。

db.employees.find()
[
{
_id: 'SF',
engineering: [
{ name: 'Alice', email: 'alice@mail.com', salary: 100000 },
{ name: 'Bob', email: 'missingEmail', salary: 75000 }
],
sales: [
{ name: 'Charlie', email: 'charlie@mail.com', salary: 90000, bonus: 1000 }
]
},
{
_id: 'NYC',
engineering: [
{ name: 'Dave', email: 'dave@mail.com', salary: 55000 }
],
sales: [
{ name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 2000 },
{ name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 10000 }
]
}
]

如上示例所示,过滤具有 engineering.email字段设立为 missingEmail 的大量元素的文档后,$ 操作符仅更新与过滤匹配的第一个匹配项。

要更新特定元素,可以使用 $elemMatch 操作符。

以下示例使用$elemMatch操作符和$操作符将 Bob 的 email更新为 "bob@mail.com"

1db.employees.updateOne(
2 { engineering: { $elemMatch: { name: "Bob", email: "missingEmail" } } },
3 { $set: { "engineering.$.email": "bob@mail.com" } }
4);

使用 find() 方法确认对 Bob电子邮件的更新。

db.employees.find(
{ "engineering": { $elemMatch: { name: "Bob" } } },
{ "engineering.$": 1, _id: 0 }
);
[
{
engineering: [ { name: 'Bob', email: 'bob@mail.com', salary: 75000 } ]
}
]

要通过单个操作更新大量的每个元素,请使用 $[] 操作符。

假设您想向纽约市的销售员工额外发放 2,000 美元的奖金。您可以使用带有updateMany() $[]操作符和$inc bonus操作符的sales 方法,将NYC 文档的 大量内的所有 字段增加2000

1db.employees.updateMany(
2 { "_id": "NYC" },
3 { "$inc": { "sales.$[].bonus": 2000 } }
4);

使用 find() 方法确认对 NYC 销售团队员工的 bonus 字段的更新。

db.employees.find(
{ _id: "NYC" },
{ sales: 1, _id: 0 }
);
[
{
sales: [
{ name: 'Ed', email: 'ed@mail.com', salary: 99000, bonus: 4000 },
{ name: 'Fran', email: 'fran@mail.com', salary: 50000, bonus: 12000 }
]
}
]

要在单个操作中更新多个大量元素,而不需要与替换操作搭配使用过多的客户端代码,请使用 $[<identifier>] 操作符。$[<identifier>] 操作符充当占位符,以更新与 arrayFilters 条件匹配的所有元素。

假设您希望在特定员工满足多个条件时更新其工资。您可以使用 updateMany() 方法和 $[<identifier>] 操作符来完成此任务。

1db.employees.updateMany(
2 {},
3 {
4 "$set": {
5 "engineering.$[elemX].salary": 95000,
6 "sales.$[elemY].salary": 75000
7 }
8 },
9 {
10 "arrayFilters": [
11 { "elemX.name": "Bob", "elemX.salary": 75000 },
12 { "elemY.name": "Ed", "elemY.salary": 50000, }
13 ]
14 }
15);

在上面的示例中,第一个参数是空匹配项,用于评估集合中的所有文档。

elemXelemY 代表两个不同的 arrayFilter:

  • 要匹配 elemX,大量对象的name字段必须为 Bobsalary 必须为 75000

  • 要匹配 elemY,大量对象的name字段必须为 Edsalary 必须为 50000

如果文档中的大量项与 elemX过滤匹配,则 updateMany() 会将该对象的 salary字段设置为 95000。如果大量项与 elemY过滤匹配,则 updateMany() 会将该对象的 salary字段设置为 75000。如果过滤不匹配,则不会触发相应的 $set 操作。

使用 find() 方法确认对 Bob 工资的更新,因为他满足 elemX 的两个条件。

db.employees.find(
{ "engineering.name": "Bob" },
{ engineering: { $elemMatch: { name: "Bob" } }, _id: 0 }
);
[
{
engineering: [
{ name: "Bob", email: "bob@mail.com", salary: 95000 }
]
}
]

使用 find() 方法确认对 Ed 工资的更新未成功,因为他不满足 elemXelemY 的条件。

db.employees.find(
{ "sales.name": "Ed" },
{ sales: { $elemMatch: { name: "Ed" } }, _id: 0 }
);
[
{
sales: [
{ name: "Ed", email: "ed@mail.com", salary: 99000, bonus: 4000 }
]
}
]

本教程将向您介绍MongoDB查询语言 (MQL) 中的一些位置操作符。这些操作符在处理数组时非常有用,因为它们使您不必对大量进行完全替换或扩展客户端操作。要学习;了解有关MQL 的更多信息,请参阅Atlas入门。

要学习;了解有关MongoDB中更新操作符的更多信息,请参阅更新操作符。

后退

方法

在此页面上