mongodb update操作数组

2,587 阅读2分钟

在上一篇mongodb update操作符之常用字段更新操作符中详细介绍了常用的字段更新操作符,本篇开始介绍操作数组需要用到的操作符以及运算修饰符。在MongoDB的模式中,我们经常将一些数据存储到数组类型中,即我们常见的嵌套模式设计的一种实现方式。数组的这种设计实现方式在关系数据库中是不常见的。关于数组的操作可以分成两类,一类是数组操作符,另一个是数组运算修饰符。

1. 数组操作符

1.1. $push

说明:

将特定的元素或值添加到数组中。可以与

语法:

{ $push: { : , ... } }

**注意:**如果要更新的文档中没有该字段,则$push将该值作为元素添加到数组字段中。

如果字段不是数组,操作将失败。

如果值是一个数组,push将整个数组作为单个元素追加。要分别添加值的每个元素,请使用push将整个数组作为单个元素追加。要分别添加值的每个元素,请使用push修饰符$each。

1.1.1. 示例

1.1.1.1. 向数组添加一个值

初始化数据:

db.inventory.insertOne({ _id: 1, item: "polarizing_filter", tags: [ ] })

示例:向数组添加一个值

db.inventory.update( { _id: 1 }, {$push: { tags: "test" } } )

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1, item: 'polarizing_filter', tags: [ 'test' ] }

1.1.1.2. 向数组添加多个值

示例:向数组添加多个值

db.inventory.update(

{ _id: 1},

{ push: { tags: { each: [ "test1", "test", "test2" ] } } }

)

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1,

item: 'polarizing_filter',

tags: [ 'test', 'test1', 'test', 'test2' ] }

1.2. $addToSet

说明:

只向集合中不存在的元素添加数组元素,addToSet不保证修改后的集合中元素的特定顺序,如果你在一个不是数组的字段上使用addToSet不保证修改后的集合中元素的特定顺序,如果你在一个不是数组的字段上使用addToSet,操作将会失败,如果值是一个数组,$addToSet将整个数组作为单个元素追加。

语法:

{ $addToSet: { : , ... } }

1.2.1. 示例

初始化数据:

db.inventory.insertOne({ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] })

**注意:**如果插入的值是在tags数组中已经存在,则不会插入。

1.2.1.1. 数组字段增加单个值

示例:追加accessories 值到tags数组字段中

db.inventory.update(

{ _id: 1 },

{ $addToSet: { tags: "accessories" } }

)

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1,

item: 'polarizing_filter',

tags: [ 'electronics', 'camera', 'accessories' ] }

1.2.1.2. 数组字段增加多个值

示例:追加多个值到tags数组字段中

db.inventory.update(

{ _id: 1},

{ addToSet: { tags: { each: [ "test", "test1", "test2" ] } } }

)

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1,

item: 'polarizing_filter',

tags: [ 'electronics', 'camera', 'accessories' ] }

1.3. $pop

说明:

pop操作符删除数组的第一个或最后一个元素。给pop操作符删除数组的第一个或最后一个元素。给pop传递一个值-1来删除数组中的第一个元素,1来删除数组中的最后一个元素。

语法:

{ $pop: { : <-1 | 1>, ... } }

**注意:**如果不是数组,则$pop操作失败。

如果$pop操作符删除中的最后一项,那么将保存一个空数组。

1.3.1. 示例

初始化数据:

db.inventory.insertOne({ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] })

**注意:**如果插入的值是在tags数组中已经存在,则不会插入。

1.3.1.1. 删除数组字段第一个元素值

示例:追加accessories 值到tags数组字段中

db.inventory.update( { _id: 1 }, { $pop: { tags: -1 } } )

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1,

item: 'polarizing_filter',

tags: [ 'camera'] }

1.3.1.2. 删除数组字段最后一个元素值

示例:追加多个值到tags数组字段中

db.inventory.update( { _id: 1 }, { $pop: { tags: 1 } } )

更改后查询:

db.inventory.findOne({"_id":1})

返回结果:

{ _id: 1,

item: 'polarizing_filter',

tags: [ ] }

1.4. $pull

说明:

pull操作符从现有数组中删除一个值或与指定条件匹配的值的所有数组元素。可以与pull操作符从现有数组中删除一个值或与指定条件匹配的值的所有数组元素。可以与each、positionposition、slice、$sort一起使用

语法:

{ $pull: { : <value|condition>, : <value|condition>, ... } }

{ $push: { : { : , ... }, ... } }

1.4.1. 示例

1.4.1.1. 删除等于指定值的所有元素

初始化数据:

db.stores.insertMany([{

_id: 1,

fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],

vegetables: [ "carrots", "celery", "squash", "carrots" ]

},

{

_id: 2,

fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],

vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]

}])

示例:下面的操作更新集合中的所有文档,从数组fruit中删除“apples”和“oranges”,并从数组vegetables中删除“carrot”:

db.stores.update(

{ },

{ pull: { fruits: { in: [ "apples", "oranges" ] }, vegetables: "carrots" } },

{ multi: true }

)

更改后查询:

db.stores.find()

返回结果:

{ _id: 1,

fruits: [ 'pears', 'grapes', 'bananas' ],

vegetables: [ 'celery', 'squash' ] }

{ _id: 2,

fruits: [ 'plums', 'kiwis', 'bananas' ],

vegetables: [ 'broccoli', 'zucchini', 'onions' ] }

1.4.1.2. 删除所有与指定的$pull条件匹配的项

初始化数据:

db.profiles.insert({ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] })

示例:下面的操作将从votes数组中删除大于或等于($gte) 6的所有元素:

db.profiles.update( { _id: 1 }, { pull: { votes: { gte: 6 } } } )

更改后查询:

db.profiles.find()

返回结果:

{ _id: 1, votes: [ 3, 5 ] }

1.4.1.3. 从文档数组中移除元素

初始化数据:

db.survey.insertMany([{

_id: 1,

results: [

{ item: "A", score: 5 },

{ item: "B", score: 8, comment: "Strongly agree" }

]

},

{

_id: 2,

results: [

{ item: "C", score: 8, comment: "Strongly agree" },

{ item: "B", score: 4 }

]

}])

示例:删除数组results字段score等于8,item等于B的元素

db.survey.update(

{ },

{ $pull: { results: { score: 8 , item: "B" } } },

{ multi: true }

)

更改后查询:

db.survey.find()

返回结果:

{ _id: 1, results: [ { item: 'A', score: 5 } ] }

{ _id: 2,

results:

[ { item: 'C', score: 8, comment: 'Strongly agree' },

{ item: 'B', score: 4 } ] }

1.5. $pullAll

说明:

从数组中移除所有匹配的值。

语法:

{ $pullAll: { : [ , ... ], ... } }

1.5.1. 示例

初始化数据:

db.testPullAll.insert({ _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] })

示例:

db.testPullAll.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } )

更改后查询:

db.testPullAll.find()

返回结果:

{ _id: 1, scores: [ 2, 1 ] }

2. 数组运算修饰符

2.1. $each

说明:

pushpush和addToSet一起使用来操作多个值

语法:

{ addToSet: { <field>: { each: [ , ... ] } } }

{ push: { <field>: { each: [ , ... ] } } }

2.2. $slice

说明:

pushpush和each一起使用来缩小更新后数组的大小。

语法:

{

$push: {

: {

$each: [ , , ... ],

$slice:

}

}

}

2.3. $sort

说明:

pushpush、each、$slice一起来排序数组中的子文档。

语法:

{

$push: {

: {

$each: [ , , ... ],

$sort:

}

}

}

2.4. $position

说明:

position修饰符指定了position修饰符指定了push操作符在数组中插入元素的位置。如果没有position修饰符,position修饰符,push操作符会将元素插入到数组的末尾,要使用position修饰符,它必须与position修饰符,它必须与each修饰符一起出现。

语法:

{

$push: {

: {

$each: [ , , ... ],

$position:

}

}

}

2.5. 使用带有多个修饰符的$push示例

初始化数据:

db.students.insert({

"_id" : 10,

"quizzes" : [

{ "wk": 1, "score" : 10 },

{ "wk": 2, "score" : 8 },

{ "wk": 3, "score" : 5 },

{ "wk": 4, "score" : 6 }

]

})

示例:以下$push操作使用:

将多个文档添加到quizzes数组的$each修饰符,

$sort修饰符按分数字段降序排序修改后的quizzes数组的所有元素

$slice修饰符只保留quizzes数组的前三个排序元素。

db.students.update(

{ _id: 10 },

{

$push: {

quizzes: {

$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],

$position: 1,

$sort: { score: -1 },

$slice: 3

}

}

}

)

更改后查询:

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

返回结果:

{ _id: 10,

quizzes:

[ { wk: 1, score: 10 },

{ wk: 2, score: 8 },

{ wk: 5, score: 8 } ] }

下一篇 mongodb之remove操作