MongoDB。如何更新数组中的 json 属性
MongoDB. How to update json property inside an array
我正在使用 Mean 堆栈。我对此很陌生,让自己陷入困境。我已经看到使用 set 或 push 更新记录的示例,但是因为我正在尝试更新 json 对象数组中 json 对象中的一个 json 对象,所以我遇到了麻烦.
考虑以下架构
token: {
type: String,
required: "FB access token required."
},
fbId: {
type: String,
required: "FB id required.",
unique: true
},
accounts: {
type: Array,
default: []
}
我的帐户数组由 json 个对象组成,每个对象如下所示:
{
"name": "some name",
"credentials": {
"username": "some username",
"password": "some password"
}
每次用户添加新帐户时,我都会尝试更新帐户。所以在这种情况下,我可以很好地使用 $push。但我不想要重名,$push 在这里失败了。所以我尝试使用 $set,但 $set 没有将具有新名称的对象插入到帐户中。所以我尝试将 upsert:true 与 $set 一起使用,但现在我遇到了重复的错误。
这是我尝试在帐户中索引名称的示例。我假设我搞砸了我的查询。
var name = "some name";
var fbId = "some fb Id";
var token = "some token";
var username = "some other username";
var password = "some other password";
var query = {
fbId: fbId,
token: token,
"accounts.name":name
};
var update = {
$set: {
accounts: [{
name: name,
credentials: {
username: username,
password: password
}
}]
}
};
var options = {
upsert: true
};
User.update(query, update, options,
function (err, numberAffected, rawResponse) {
//handle it
});
);
总结一下我的问题,认为我可以通过一个电话更新它是否合理?如果可以,如何更新?或者我应该找到该对象,替换它的值,然后将它重新插入到数据库中吗?
如果 $push
适合您,但您想避免向数组中添加重复项,请尝试 $addToSet
。它会向数组添加一个值,只要该值不在其中即可。查看 $addToSet 文档。
更新
从你原来的post:
I'm trying to update accounts each time the user adds a new one. So in
this case I can use $push just fine. But I don't want duplicate names,
and $push fails here.
var uniqueAccount = {
name:'unique account',
credentials: {
username:'new username',
password:'some secret password'
}
};
db.accounts.update({fbId: fbId, token: token},
{accounts: {$addToSet: uniqueAccount}});
您可以使用 $
数组更新运算符:
var query = {
fbId: fbId,
token: token,
"accounts.name":name
};
var update = {
$set: {
"accounts.$": [{ //The $ operator goes into the update object
name: name,
credentials: {
username: username,
password: password
}
}]
}
};
根据 documentation:
The positional $ operator identifies an element in an array to update
without explicitly specifying the position of the element in the
array.
编辑:
根据此 MongoDB JIRA page,将 upsert 与 $ 位置运算符一起使用仍然是一个悬而未决的问题。
我四处搜索并找到了一个可能的解决方案,但不幸的是,这无法实现您通过一个电话实现这一目标的目标。可以查到here.
总而言之,您必须先发送不带 upsert
标志的更新查询。然后检查响应以查看文档是否已更新,如果没有(这意味着不存在这样的子文档),请使用 $push
运算符发送另一个查询以在数组中插入新的子文档。
我正在使用 Mean 堆栈。我对此很陌生,让自己陷入困境。我已经看到使用 set 或 push 更新记录的示例,但是因为我正在尝试更新 json 对象数组中 json 对象中的一个 json 对象,所以我遇到了麻烦.
考虑以下架构
token: {
type: String,
required: "FB access token required."
},
fbId: {
type: String,
required: "FB id required.",
unique: true
},
accounts: {
type: Array,
default: []
}
我的帐户数组由 json 个对象组成,每个对象如下所示:
{
"name": "some name",
"credentials": {
"username": "some username",
"password": "some password"
}
每次用户添加新帐户时,我都会尝试更新帐户。所以在这种情况下,我可以很好地使用 $push。但我不想要重名,$push 在这里失败了。所以我尝试使用 $set,但 $set 没有将具有新名称的对象插入到帐户中。所以我尝试将 upsert:true 与 $set 一起使用,但现在我遇到了重复的错误。
这是我尝试在帐户中索引名称的示例。我假设我搞砸了我的查询。
var name = "some name";
var fbId = "some fb Id";
var token = "some token";
var username = "some other username";
var password = "some other password";
var query = {
fbId: fbId,
token: token,
"accounts.name":name
};
var update = {
$set: {
accounts: [{
name: name,
credentials: {
username: username,
password: password
}
}]
}
};
var options = {
upsert: true
};
User.update(query, update, options,
function (err, numberAffected, rawResponse) {
//handle it
});
);
总结一下我的问题,认为我可以通过一个电话更新它是否合理?如果可以,如何更新?或者我应该找到该对象,替换它的值,然后将它重新插入到数据库中吗?
如果 $push
适合您,但您想避免向数组中添加重复项,请尝试 $addToSet
。它会向数组添加一个值,只要该值不在其中即可。查看 $addToSet 文档。
更新
从你原来的post:
I'm trying to update accounts each time the user adds a new one. So in this case I can use $push just fine. But I don't want duplicate names, and $push fails here.
var uniqueAccount = {
name:'unique account',
credentials: {
username:'new username',
password:'some secret password'
}
};
db.accounts.update({fbId: fbId, token: token},
{accounts: {$addToSet: uniqueAccount}});
您可以使用 $
数组更新运算符:
var query = {
fbId: fbId,
token: token,
"accounts.name":name
};
var update = {
$set: {
"accounts.$": [{ //The $ operator goes into the update object
name: name,
credentials: {
username: username,
password: password
}
}]
}
};
根据 documentation:
The positional $ operator identifies an element in an array to update without explicitly specifying the position of the element in the array.
编辑:
根据此 MongoDB JIRA page,将 upsert 与 $ 位置运算符一起使用仍然是一个悬而未决的问题。
我四处搜索并找到了一个可能的解决方案,但不幸的是,这无法实现您通过一个电话实现这一目标的目标。可以查到here.
总而言之,您必须先发送不带 upsert
标志的更新查询。然后检查响应以查看文档是否已更新,如果没有(这意味着不存在这样的子文档),请使用 $push
运算符发送另一个查询以在数组中插入新的子文档。