我刚刚升级到Mongo 2.6.1,之前正在运行的一个更新语句没有返回错误.更新声明是:
db.post.update( { 'answers.comments.name': 'jeff' },
{ '$set': {
'answers.$.comments.$.name': 'joe'
}},
{ multi: true }
)
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 2,
"errmsg" : "Too many positional (i.e. '$') elements found in path 'answers.$.comments.$.createUsername'"
}
})
Run Code Online (Sandbox Code Playgroud)
当我更新一个元素只有一个深度而不是两个(即answers.$.name代替answers.$.comments.$.name),它工作正常.如果我将我的mongo实例降级到2.6以下,它也可以正常工作.
Com*_*rch 17
你CAN做到这一点,你只需要蒙戈3.6!您可以使用 Mongo 3.6 中的 Array Filters 功能,而不是重新设计您的数据库,该功能可以在这里找到:
https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters
这样做的好处是您可以将数组中的所有匹配项绑定到一个变量,然后稍后再引用该变量。这是上面链接中的主要示例:
kar*_*oon 12
使用arrayFilters.
MongoDB 3.5.12 扩展了所有更新修饰符以应用于所有数组元素或与谓词匹配的所有数组元素,在新的更新选项 arrayFilters 中指定。此语法还支持嵌套数组元素。
让我们假设一个场景——
"access": {
"projects": [{
"projectId": ObjectId(...),
"milestones": [{
"milestoneId": ObjectId(...),
"pulses": [{
"pulseId": ObjectId(...)
}]
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
现在,如果您想向项目中存在的里程碑添加一个脉冲
db.users.updateOne({
"_id": ObjectId(userId)
}, {
"$push": {
"access.projects.$[i].milestones.$[j].pulses": ObjectId(pulseId)
}
}, {
arrayFilters: [{
"i.projectId": ObjectId(projectId)
}, {
"j.milestoneId": ObjectId(milestoneId)
}]
})
Run Code Online (Sandbox Code Playgroud)
对于PyMongo,像这样使用 arrayFilters -
db.users.update_one({
"_id": ObjectId(userId)
}, {
"$push": {
"access.projects.$[i].milestones.$[j].pulses": ObjectId(pulseId)
}
}, array_filters = [{
"i.projectId": ObjectId(projectId)
}, {
"j.milestoneId": ObjectId(milestoneId)
}])
Run Code Online (Sandbox Code Playgroud)
还,
每个数组过滤器都必须是具有单个字段名称的文档的谓词。每个数组过滤器都必须在更新表达式中使用,并且每个数组过滤器标识符 $[] 必须有一个对应的数组过滤器。必须以小写字母开头且不包含任何特殊字符。不得有两个具有相同字段名称的数组过滤器。
https://jira.mongodb.org/browse/SERVER-831
Ger*_*osi 11
位置运算符只能在查询中使用一次.这是一个限制,有一个开放的改进票:https://jira.mongodb.org/browse/SERVER-831
如前所述; 目前不支持多个位置元素。您可以使用mongodb cursor.forEach()方法进行更新。
db.post
.find({"answers.comments.name": "jeff"})
.forEach(function(post) {
if (post.answers) {
post.answers.forEach(function(answer) {
if (answer.comments) {
answer.comments.forEach(function(comment) {
if (comment.name === "jeff") {
comment.name = "joe";
}
});
}
});
db.post.save(post);
}
});
Run Code Online (Sandbox Code Playgroud)
小智 5
db.post.update(
{ 'answers.comments.name': 'jeff' },
{ '$set': {
'answers.$[i].comments.$.name': 'joe'
}},
{arrayFilters: [ { "i.comments.name": { $eq: 'jeff' } } ]}
)Run Code Online (Sandbox Code Playgroud)
answers获取正确的关键路径
| 归档时间: |
|
| 查看次数: |
6999 次 |
| 最近记录: |