【Node.js】mongoose教程08--更新

文章目錄
  1. 1. Query.update()
  2. 2. 全量更新
  3. 3. 指定字段更新
  4. 4. 數組的更新

本文是存儲了5個手機數據後再操作的。存儲實現見文章:【Node.js】mongoose教程—存儲

GitHub源碼鏈接:sodino#MongoDemo


Query.update()

官方文檔鏈接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
Query#update([criteria], [doc], [options], [callback])
Declare and/or execute this query as an update() operation.
Parameters:
[criteria] <Object>
[doc] <Object> the update command
[options] <Object>
[callback] <Function>
Returns:
<Query> this
See:
Model.update
update
All paths passed that are not $atomic operations will become $set ops.
Example
Model.where({ _id: id }).update({ title: 'words' })
// becomes
Model.where({ _id: id }).update({ $set: { title: 'words' }})
Valid options:
safe (boolean) safe mode (defaults to value set in schema (true))
upsert (boolean) whether to create the doc if it doesn't match (false)
multi (boolean) whether multiple documents should be updated (false)
runValidators: if true, runs update validators on this command. Update validators validate the update operation against the model's schema.
setDefaultsOnInsert: if this and upsert are true, mongoose will apply the defaults specified in the model's schema if a new document is created. This option only works on MongoDB >= 2.4 because it relies on MongoDB's $setOnInsert operator.
strict (boolean) overrides the strict option for this update
overwrite (boolean) disables update-only mode, allowing you to overwrite the doc (false)
context (string) if set to 'query' and runValidators is on, this will refer to the query in custom validator functions that update validation runs. Does nothing if runValidators is false.
Note
Passing an empty object {} as the doc will result in a no-op unless the overwrite option is passed. Without the overwrite option set, the update operation will be ignored and the callback executed without sending the command to MongoDB so as to prevent accidently overwritting documents in the collection.
Note
The operation is only executed when a callback is passed. To force execution without a callback (which would be an unsafe write), we must first call update() and then execute it by using the exec() method.
var q = Model.where({ _id: id });
q.update({ $set: { name: 'bob' }}).update(); // not executed
q.update({ $set: { name: 'bob' }}).exec(); // executed as unsafe
// keys that are not $atomic ops become $set.
// this executes the same command as the previous example.
q.update({ name: 'bob' }).exec();
// overwriting with empty docs
var q = Model.where({ _id: id }).setOptions({ overwrite: true })
q.update({ }, callback); // executes
// multi update with overwrite to empty doc
var q = Model.where({ _id: id });
q.setOptions({ multi: true, overwrite: true })
q.update({ });
q.update(callback); // executed
// multi updates
Model.where()
.update({ name: /^match/ }, { $set: { arr: [] }}, { multi: true }, callback)
// more multi updates
Model.where()
.setOptions({ multi: true })
.update({ $set: { arr: [] }}, callback)
// single update by default
Model.where({ email: '[email protected]' })
.update({ $inc: { counter: 1 }}, callback)
API summary
update(criteria, doc, options, cb) // executes
update(criteria, doc, options)
update(criteria, doc, cb) // executes
update(criteria, doc)
update(doc, cb) // executes
update(doc)
update(cb) // executes
update(true) // executes (unsafe write)
update()

需要指出的是Query.update()在該方法沒有回調參數callback或沒有在鏈式代碼末尾添加.exec(callback)時是不會真正去執行查詢的。

更新的功能看文檔就好了,這章不想寫…直接看下面代碼吧


全量更新

Query.update()存儲,即全量更新。
如下代碼中是將phone對象所有的內容再存儲一篇,雖然本來操作的意圖只是想簡單的更改device

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
raw = require('./raw.huawei.Mate8.json');
var huaweiMate8 = new Phone(raw);
huaweiMate8.device = ‘Huawei Mate 8000';
Phone.update({_id : huaweiMate8._id},
phone, // json對象即可
{safe : true, upsert : true},
(err, rawResponse)=>{
console.log('---updateDeviceName()---------------------------------');
if (err) {
console.log(err);
} else {
console.log(rawResponse);
Phone.findOne({_id : phone._id}, (err, phone) => {
console.log('---device update to "Huawei Mate 8000"---------------------------------');
if (err) {
console.log(err);
} else {
console.log(phone);
}
addApps(phone);
});
}
}
);

控制檯輸出如下:

update


指定字段更新

在上面的代碼中只更新了字段device,但實際卻是將其它字段一併覆蓋掉原有值了,雖然前後值是一樣的,但明顯可以用指定字段更新的方式獲得更高的更新效率。

如下替換即可:

1
2
3
4
5
Phone.update({_id: huaweiMate8._id},
{device : 'Huawei Mate 8000'},
.... ....//其它代碼一模一樣
);

當然,也可以用$set操作符來實現,代碼如下:

1
2
3
4
5
Phone.update({_id: huaweiMate8._id},
{$set : {device : 'Huawei Mate 8000'}},
.... ....//其它代碼一模一樣
);

數組的更新

數組的更新有以下幾種操作:

1
2
3
4
5
6
$addToSet // 當且僅當待添加到數組的元素是當前數組所沒有時,纔會去添加
$pop // 當指定數組的修飾符值爲-1時,刪除該數組的第1個元素;當值爲1時,刪除最後一個元素
$pull // 刪除指定查詢條件下的數組元素
$pullAll // 刪除數組中符合給定的集合的值的所有元素,與$pull的區別於目標刪除元素是被逐一列舉出來的
$push // 將元素添加到指定的數組中
$pushAll // 在2.4版本後建議不再使用,Sodino寫累了也不想說了

以下演示往Phone.apps數組中添加新應用58City,代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
// 以下兩種方式都可以
// 保存phone的全部信息
phone.apps.push({name : "58City"});
Phone.update({_id : phone._id},
phone,
{safe : true, upsert : true},
(err, rawResponse) => {
console.log('---addApps()---------------------------------');
if (err) {
console.log(err);
} else {
console.log(rawResponse);
Phone.findOne({_id : phone._id}, (err, phone) => {
console.log('---app:58City added.---------------------------------');
if (err) {
console.log(err);
} else {
console.log(phone);
}
});
}
}
);
// 只修改apps 這個數組
Phone.update({_id : phone._id},
{$push : {apps : {name : '58City'}}},
{safe : true, upsert : true},
(err, rawResponse)=>{
console.log('---addApps()---------------------------------');
if (err) {
console.log(err);
} else {
console.log(rawResponse);
Phone.findOne({_id : phone._id}, (err, phone) => {
console.log('---app:58City added.---------------------------------');
if (err) {
console.log(err);
} else {
console.log(phone);
}
});
}
}
);

控制檯輸出如下:
addApps


相關鏈接:
Filed Update Operators
Array Update Operators


下一篇mongoose教程—刪除


About Sodino

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章