尝试使用 Sails.js 和 Waterline ORM 更新 MongoDB 子文档中的单个键时遇到问题。这就是我的 person.js
模型的样子:
module.exports = {
attributes: {
name: { type: 'string', required: true },
favorites: {
type: 'json',
defaultsTo: {
color: null,
place: null,
season: null
}
}
}
}
现在,假设我想从我的 Controller 更新特定人的名字和最喜欢的季节,我正在这样做:
Person.update({ id: '1' }, {
name: 'Dan',
favorites: {
season: 'Summer'
}
}).exec(function(error, updatedPerson) {
console.log(updatedPerson);
});
当我运行这个时,favorites
对象被完全替换为只有我更新的一个键(季节键),而不是在更新时保留其他两个键(颜色和位置)我想要的那个。我缺少什么?如何让它只更新我指定的 key ?
最佳答案
您可以使用.native()
模型上的方法可以直接访问 mongo 驱动程序,然后是 $set
运算符(operator)独立更新字段。但是,您需要首先将对象转换为具有点符号的单级文档,例如
{
"name": "Dan",
"favorites.season": "Summer"
}
这样您就可以将其用作:
var criteria = { "id": "1" },
update = { "$set": { "name": "Dan", "favorites.season": "Summer" } },
options = { "new": true };
// Grab an instance of the mongo-driver
Person.native(function(err, collection) {
if (err) return res.serverError(err);
// Execute any query that works with the mongo js driver
collection.findAndModify(
criteria,
null,
update,
options,
function (err, updatedPerson) {
console.log(updatedPerson);
}
);
});
要转换需要更新的原始对象,请使用以下函数
var convertNestedObjectToDotNotation = function(obj){
var res = {};
(function recurse(obj, current) {
for(var key in obj) {
var value = obj[key];
var newKey = (current ? current + "." + key : key); // joined key with dot
if (value && typeof value === "object") {
recurse(value, newKey); // it's a nested object, so do it again
} else {
res[newKey] = value; // it's not an object, so set the property
}
}
})(obj);
return res;
}
然后您可以在更新中调用它
var criteria = { "id": "1" },
update = { "$set": convertNestedObjectToDotNotation(params) },
options = { "new": true };
查看下面的演示。
var example = {
"name" : "Dan",
"favorites" : {
"season" : "winter"
}
};
var convertNestedObjectToDotNotation = function(obj){
var res = {};
(function recurse(obj, current) {
for(var key in obj) {
var value = obj[key];
var newKey = (current ? current + "." + key : key); // joined key with dot
if (value && typeof value === "object") {
recurse(value, newKey); // it's a nested object, so do it again
} else {
res[newKey] = value; // it's not an object, so set the property
}
}
})(obj);
return res;
}
var update = { "$set": convertNestedObjectToDotNotation(example) };
pre.innerHTML = "update = " + JSON.stringify(update, null, 4);
<pre id="pre"></pre>
关于javascript - 如何使用 Sails.js 和 Waterline 更新 MongoDB 子文档中的特定键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40741373/