本文是存储了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: 'address@example.com' })
.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