mongodb update操作符之常用字段更新操作符

3,114 阅读4分钟

在上一篇 mongodb基础操作之update更新操作 中详细介绍了mongodb update API的基础用法,接下来详细介绍update更新需要用到的常用字段更新操作符。

mongodb中的更新操作符分为 字段更新运算符、数组更新运算符和按位更新运算符三种,本文详细介绍常用的字段更新运算操作符。

以下修饰符可用于更新操作;

例如在db.collection.update()和db.collection.findAndModify()中。

语法如下:

{

: { : , ... },

: { : , ... },

...

}

1. $set

说明:

set操作符将字段的值设置为指定的值,如果该字段不存在,set操作符将字段的值设置为指定的值,如果该字段不存在,set将添加一个具有指定值的新字段。

语法:

{ $set: { : , ... } }

**注意:**若要在嵌入式文档或数组中指定<字段>,请使用点表示法。

1.1. 示例

初始化数据:

db.products.insert({

_id: 100,

sku: "abc123",

quantity: 250,

instock: true,

reorder: false,

details: { model: "14Q2", make: "xyz" },

tags: [ "apparel", "clothing" ],

ratings: [ { by: "ijk", rating: 4 } ]

})

1.1.1. 更新单个对象字段

示例:查询_id等于100的条件的文档,使用$set操作符更新quantity字段、details字段和tags字段的值。

db.products.update(

{ _id: 100 },

{ $set:

{

quantity: 500,

details: { model: "14Q3", make: "xyz" },

tags: [ "coats", "outerwear", "clothing" ]

}

}

)

更改后查询:

db.products.find({"_id":100}).pretty()

返回结果:

{

"_id" : 100,

"sku" : "abc123",

"quantity" : 500,

"instock" : true,

"reorder" : false,

"details" : {

"model" : "14Q3",

"make" : "xyz"

},

"tags" : [

"coats",

"outerwear",

"clothing"

],

"ratings" : [

{

"by" : "ijk",

"rating" : 4

}

]

}

1.1.2. 更新嵌入文档中的字段

示例:查询_id等于100的条件的文档,使用$set操作符更新details对象中的make字段值。

db.products.update(

{ _id: 100 },

{ $set: { "details.make": "zzz" } }

)

更改后查询:

db.products.find({"_id":100}).pretty()

返回结果:

{

"_id" : 100,

"sku" : "abc123",

"quantity" : 500,

"instock" : true,

"reorder" : false,

"details" : {

"model" : "14Q3",

"make" : "zzz"

},

"tags" : [

"coats",

"outerwear",

"clothing"

],

"ratings" : [

{

"by" : "ijk",

"rating" : 4

}

]

}

1.1.3. 更新数组字段

示例:查询_id等于100的条件的文档,使用$set操作符更新tags字段中的第二个元素(数组索引为1)和ratings数组的第一个元素(数组索引为0)中的ratings字段的值。

db.products.update(

{ _id: 100 },

{ $set:

{

"tags.1": "rain gear",

"ratings.0.rating": 2

}

}

)

更改后查询:

db.products.find({"_id":100}).pretty()

返回结果:

{

"_id" : 100,

"sku" : "abc123",

"quantity" : 500,

"instock" : true,

"reorder" : false,

"details" : {

"model" : "14Q3",

"make" : "zzz"

},

"tags" : [

"coats",

"rain gear",

"clothing"

],

"ratings" : [

{

"by" : "ijk",

"rating" : 2

}

]

}

2. $unset

说明:

unset操作符删除特定字段,如果字段不存在,则unset操作符删除特定字段,如果字段不存在,则unset不做任何操作。

语法:

{ $unset: { : "", ... } }

2.1. 示例

初始化数据:

db.products.insert({

_id: 100,

sku: "abc123",

quantity: 250,

instock: true,

reorder: false,

details: { model: "14Q2", make: "xyz" },

tags: [ "apparel", "clothing" ],

ratings: [ { by: "ijk", rating: 4 } ]

})

示例:筛选出sku为abc123的记录,并删除quantity和instock字段

db.products.update(

{ sku: "abc123" },

{ $unset: { quantity: "", instock: "" } }

)

更改后查询:

db.products.find({"sku":"abc123"}).pretty()

返回结果:

{

"_id" : 100,

"sku" : "abc123",

"reorder" : false,

"details" : {

"model" : "14Q3",

"make" : "zzz"

},

"tags" : [

"coats",

"rain gear",

"clothing"

],

"ratings" : [

{

"by" : "ijk",

"rating" : 2

}

]

}

3. $setOnInsert

说明:

如果update和findAndModify api的upsert参数为 true时,更新操作导致插入文档,则setOnInsert将指定的值赋给文档中的字段。如果更新操作没有导致插入,则setOnInsert将指定的值赋给文档中的字段。如果更新操作没有导致插入,则setOnInsert不做任何操作。

语法:

db.collection.update(

,

{ $setOnInsert: { : , ... } },

{ upsert: true }

)

3.1. 示例

初始化数据:

db.products.insert({

_id: 100,

sku: "abc123",

quantity: 250,

instock: true,

reorder: false,

details: { model: "14Q2", make: "xyz" },

tags: [ "apparel", "clothing" ],

ratings: [ { by: "ijk", rating: 4 } ]

})

示例:筛选出sku为abc123的记录,并删除quantity和instock字段

db.products.update(

{ _id: 100 },

{

$set: { item: "apple" },

$setOnInsert: { defaultQty: 100 }

},

{ upsert: true }

)

更改后查询:

db.products.find({"_id":100}).pretty()

返回结果:因为已经存在id为100的文档记录,所以defaultQty字段没有被插入。如果不存在

{id为100的文档记录,则defaultQty字段会被插入

"_id" : 100,

"sku" : "abc123",

"reorder" : false,

"details" : {

"model" : "14Q3",

"make" : "zzz"

},

"tags" : [

"coats",

"rain gear",

"clothing"

],

"ratings" : [

{

"by" : "ijk",

"rating" : 2

}

],

"item" : "apple"

}

4. $rename

说明:

更新字段的名称,新字段名称必须与现有字段名称不同。

语法:

{$rename: { : , : , ... } }

注意:

rename操作符在逻辑上同时执行旧名称和新名称的rename操作符在逻辑上同时执行旧名称和新名称的unset操作,然后使用新名称执行$set操作。因此,操作可能不会保留文档中字段的顺序;也就是说,重命名的字段可以在文档中移动。

如果文档中已经有一个字段,则$rename操作符会删除该字段,并将指定的重命名为。

如果要重命名的字段在文档中不存在,则$rename不做任何操作。

对于嵌入文档中的字段,rename操作符可以重命名这些字段,并将字段移入或移出嵌入文档。如果这些字段在数组元素中,rename操作符可以重命名这些字段,并将字段移入或移出嵌入文档。如果这些字段在数组元素中,rename不起作用。

4.1. 示例

初始化数据:

db.students.insertMany([{

"_id": 1,

"alias": [ "The American Cincinnatus", "The American Fabius" ],

"mobile": "555-555-5555",

"nmae": { "first" : "george", "last" : "washington" }

},

{

"_id": 2,

"alias": [ "My dearest friend" ],

"mobile": "222-222-2222",

"nmae": { "first" : "abigail", "last" : "adams" }

},

{

"_id": 3,

"alias": [ "Amazing grace" ],

"mobile": "111-111-1111",

"nmae": { "first" : "grace", "last" : "hopper" }

}])

4.1.1. 重命名单个对象字段

示例:nmae字段重命名为name

db.students.updateMany( {}, { $rename: { "nmae": "name" } } )

更改后查询:

db.students.find()

返回结果:

{ "_id" : 2, "alias" : [ "My dearest friend" ], "mobile" : "222-222-2222", "name" : { "first" : "abigail", "last" : "adams" } }

{ "_id" : 3, "alias" : [ "Amazing grace" ], "mobile" : "111-111-1111", "name" : { "first" : "grace", "last" : "hopper" } }

{ "_id" : 1, "alias" : [ "The American Cincinnatus", "The American Fabius" ], "mobile" : "555-555-5555", "name" : { "first" : "george", "last" : "washington" } }

4.1.2. 重命名嵌入文档中的字段

要重命名嵌入文档中的字段,可以使用点表示法调用$rename操作符来引用该字段。如果该字段保留在同一个嵌入文档中,也可以在新名称中使用点符号,如下所示:

db.students.update( { _id: 1 }, { $rename: { "name.first": "name.fname" } } )

更改后查询:

db.students.find({"_id":1})

返回结果:

{ "_id" : 1, "alias" : [ "The American Cincinnatus", "The American Fabius" ], "mobile" : "555-555-5555", "name" : { "last" : "washington", "fname" : "george" } }

5. $inc

说明:

将一个字段增加一个指定的值,该操作接受正值和负值。如果该字段不存在,请inc创建该字段并将该字段设置为指定的值,在null值的字段上使用inc创建该字段并将该字段设置为指定的值,在null值的字段上使用inc操作符将产生错误。

语法:

{ $inc: { : , : , ... } }

5.1. 示例

初始化数据:

db.products.insert({

_id: 1,

sku: "abc123",

quantity: 10,

metrics: {

orders: 2,

ratings: 3.5

}

})

示例:quantity字段值减2,metrics.orders字段值加1

db.products.update(

{ sku: "abc123" },

{ $inc: { quantity: -2, "metrics.orders": 1 } }

)

更改后查询:

db.products.find({"sku":"abc123"}).pretty()

返回结果:

{

"_id" : 1,

"sku" : "abc123",

"quantity" : 8,

"metrics" : {

"orders" : 3,

"ratings" : 3.5

}

}

6. $currentDate

说明:

currentDate操作符将字段的值设置为当前日期,可以是日期或时间戳。默认类型为Date,如果该字段不存在,则currentDate操作符将字段的值设置为当前日期,可以是日期或时间戳。默认类型为Date,如果该字段不存在,则currentDate将该字段添加到文档中。

语法:

{ $currentDate: { : , ... } }

可以是:

一个布尔值true,用于将当前日期的字段值设置为日期,或

文档{type: "timestamp"}或{type: "date"}显式指定类型。运算符区分大小写,只接受小写的“timestamp”或小写的“date”。

6.1. 示例

初始化数据:

db.customers.insertOne(

{ _id: 1, status: "a", lastModified: ISODate("2013-10-02T01:11:18.965Z") }

)

示例:将lastModified字段更新为当前日期,增加cancellation.date字段,设置值为当前时间戳,增加cancellation.reason字段,设置值为user request,status字段设置为D

db.customers.updateOne(

{ _id: 1 },

{

$currentDate: {

lastModified: true,

"cancellation.date": { $type: "timestamp" }

},

$set: {

"cancellation.reason": "user request",

status: "D"

}

}

)

更改后查询:

db.customers.find().pretty()

返回结果:

{

"_id" : 1,

"status" : "D",

"lastModified" : ISODate("2021-01-21T09:22:56.639Z"),

"cancellation" : {

"date" : Timestamp(1611220976, 1),

"reason" : "user request"

}

}

下一篇 mongodb update操作数组