Ответ 1
Оператор позиционирования может использоваться только один раз в запросе. Это ограничение, есть открытый билет для улучшения: https://jira.mongodb.org/browse/SERVER-831
Я только что обновился до Mongo 2.6.1, и один оператор обновления, который работал раньше, не возвращает ошибку. Оператор обновления:
db.post.update( { 'answers.comments.name': 'jeff' },
{ '$set': {
'answers.$.comments.$.name': 'joe'
}},
{ multi: true }
)
Ошибка, которую я получаю:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 2,
"errmsg" : "Too many positional (i.e. '$') elements found in path 'answers.$.comments.$.createUsername'"
}
})
Когда я обновляю элемент только на один уровень, а не на два (т.е. answers.$.name
вместо answers.$.comments.$.name
), он отлично работает. Если я уменьшу свой экземпляр mongo ниже 2.6, он также отлично работает.
Оператор позиционирования может использоваться только один раз в запросе. Это ограничение, есть открытый билет для улучшения: https://jira.mongodb.org/browse/SERVER-831
Я столкнулся с той же проблемой, так как массив внутри массива требует значительного влияния на производительность. Таким образом, mongo db не поддерживает его. Переработайте свою базу данных, как показано в приведенной ссылке ниже.
https://pythonolyk.wordpress.com/2016/01/17/mongodb-update-nested-array-using-positional-operator/
Как упоминалось; на данный момент не поддерживается более одного позиционного элемента. Вы можете обновить с помощью метода 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);
}
});
db.post.update( { 'answers.comments.name': 'jeff' },
{ '$set': {
'answers.$.comments.$.name': 'joe'
}},
{ multi: true }
)
Ответ
db.post.update( { 'answers.comments.name': 'jeff' },
{ '$set': {
'answers.0.comments.1.name': 'joe'
}},
{ multi: true }
)