5、db.update(query, update, options, callback)

作用:

根据 update 参数的规则,更新匹配到 query 的结果集。

参数:

query: 与 find 和 findOne 中 query 参数的用法一致

update: 指定文档更改规则。该参数可以是一个新的文档,也可以是一套修饰符,两者不能同时使用。使用修饰符时,如果需要更改的字段不存在,将会自动创建。可用的修饰符有 $set(改变字段值), $unset(删除某一字段), $inc(增加某一字段), $min/$max(改变字段值,传入值需要小于/大于当前值), 还有一些用在数组上的修饰符,$push, $pop, $addTopSet, $pull, $each, $slice,具体用法如下示例。

options: object 类型。muti(默认 false),是否允许修改多条文档;upsert(默认为 false),如果 query 没有匹配到结果集,有两种情况需要考虑,一个是 update 是一个简单的对象 (不包含任何修饰符),另一种情况是带有修饰符,对第一种情况会直接将该文档插入,对第二种情况会将通过修饰符更改后的文档插入;

callback(可选): 参数 (err, numAffected, affectedDocuments, upsert)。numAffected:被影响的文档个数;affectedDocuments:更新后的文档。

注意:_id 不能被修改

示例:

  1. // 文档集
  2. // { _id: 'id1', planet: 'Mars', system: 'solar', inhabited: false }
  3. // { _id: 'id2', planet: 'Earth', system: 'solar', inhabited: true }
  4. // { _id: 'id3', planet: 'Jupiter', system: 'solar', inhabited: false }
  5. // { _id: 'id4', planet: 'Omicron Persia 8', system: 'futurama', inhabited: true }
  6. // 用一个文档替换另一个文档
  7. db.update({planet:'Jupiter'},{planet:'Pluton'},{},function(err,numReplaced){
  8. // numReplaced = 1
  9. // The doc #3 has been replaced by { _id: 'id3', planet: 'Pluton' }
  10. // Note that the _id is kept unchanged, and the document has been replaced
  11. // (the 'system' and inhabited fields are not here anymore)
  12. });
  13. // 设定一个已存字段的值
  14. db.update({system:'solar'},{$set:{system:'solar system'}},{multi:true},function(err,numReplaced){
  15. // numReplaced = 3
  16. // Field 'system' on Mars, Earth, Jupiter now has value 'solar system'
  17. });
  18. // 设定一个不存在字段的值
  19. db.update({planet:'Mars'},{$set:{"data.satellites":2,"data.red":true}},{},function(){
  20. // Mars document now is { _id: 'id1', system: 'solar', inhabited: false
  21. // , data: { satellites: 2, red: true }
  22. // }
  23. // Not that to set fields in subdocuments, you HAVE to use dot-notation
  24. // Using object-notation will just replace the top-level field
  25. db.update({planet:'Mars'},{$set:{data:{satellites:3}}},{},function(){
  26. // Mars document now is { _id: 'id1', system: 'solar', inhabited: false
  27. // , data: { satellites: 3 }
  28. // }
  29. // You lost the "data.red" field which is probably not the intended behavior
  30. });
  31. });
  32. // 删除一个字段
  33. db.update({planet:'Mars'},{$unset:{planet:true}},{},function(){
  34. // Now the document for Mars doesn't contain the planet field
  35. // You can unset nested fields with the dot notation of course
  36. });
  37. // 设置upsert
  38. db.update({planet:'Pluton'},{planet:'Pluton',inhabited:false},{upsert:true},function(err,numReplaced,upsert){
  39. // numReplaced = 1, upsert = { _id: 'id5', planet: 'Pluton', inhabited: false }
  40. // A new document { _id: 'id5', planet: 'Pluton', inhabited: false } has been added to the collection
  41. });
  42. // If you upsert with a modifier, the upserted doc is the query modified by the modifier
  43. // This is simpler than it sounds :)
  44. db.update({planet:'Pluton'},{$inc:{distance:38}},{upsert:true},function(){
  45. // A new document { _id: 'id5', planet: 'Pluton', distance: 38 } has been added to the collection
  46. });
  47. // If we insert a new document { _id: 'id6', fruits: ['apple', 'orange', 'pear'] } in the collection,
  48. // let's see how we can modify the array field atomically
  49. // $push inserts new elements at the end of the array
  50. db.update({_id:'id6'},{$push:{fruits:'banana'}},{},function(){
  51. // Now the fruits array is ['apple', 'orange', 'pear', 'banana']
  52. });
  53. // $pop removes an element from the end (if used with 1) or the front (if used with -1) of the array
  54. db.update({_id:'id6'},{$pop:{fruits:1}},{},function(){
  55. // Now the fruits array is ['apple', 'orange']
  56. // With { $pop: { fruits: -1 } }, it would have been ['orange', 'pear']
  57. });
  58. // $addToSet adds an element to an array only if it isn't already in it
  59. // Equality is deep-checked (i.e. $addToSet will not insert an object in an array already containing the same object)
  60. // Note that it doesn't check whether the array contained duplicates before or not
  61. db.update({_id:'id6'},{$addToSet:{fruits:'apple'}},{},function(){
  62. // The fruits array didn't change
  63. // If we had used a fruit not in the array, e.g. 'banana', it would have been added to the array
  64. });
  65. // $pull removes all values matching a value or even any NeDB query from the array
  66. db.update({_id:'id6'},{$pull:{fruits:'apple'}},{},function(){
  67. // Now the fruits array is ['orange', 'pear']
  68. });
  69. db.update({_id:'id6'},{$pull:{fruits:$in:['apple','pear']}},{},function(){
  70. // Now the fruits array is ['orange']
  71. });
  72. // $each can be used to $push or $addToSet multiple values at once
  73. // This example works the same way with $addToSet
  74. db.update({_id:'id6'},{$push:{fruits:{$each:['banana','orange']}}},{},function(){
  75. // Now the fruits array is ['apple', 'orange', 'pear', 'banana', 'orange']
  76. });
  77. // $slice can be used in cunjunction with $push and $each to limit the size of the resulting array.
  78. // A value of 0 will update the array to an empty array. A positive value n will keep only the n first elements
  79. // A negative value -n will keep only the last n elements.
  80. // If $slice is specified but not $each, $each is set to []
  81. db.update({_id:'id6'},{$push:{fruits:{$each:['banana'],$slice:2}}},{},function(){
  82. // Now the fruits array is ['apple', 'orange']
  83. });
  84. // $min/$max to update only if provided value is less/greater than current value
  85. // Let's say the database contains this document
  86. // doc = { _id: 'id', name: 'Name', value: 5 }
  87. db.update({_id:'id1'},{$min:{value:2}},{},function(){
  88. // The document will be updated to { _id: 'id', name: 'Name', value: 2 }
  89. });
  90. db.update({_id:'id1'},{$min:{value:8}},{},function(){
  91. // The document will not be modified
  92. });