MongoDB: 경로에 위치(예: '$') 요소가 너무 많습니다.
방금 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
), 잘 작동합니다.내 몽고 인스턴스를 2.6 이하로 다운그레이드하면 역시 잘 작동합니다.
사용하다arrayFilters
.
MongoDB 3.5.12는 새 업데이트 옵션 arrayFilters에 지정된 술어와 일치하는 모든 어레이 요소 또는 모든 어레이 요소에 적용할 수 있도록 모든 업데이트 한정자를 확장합니다.이 구문은 중첩된 배열 요소도 지원합니다.
시나리오를 가정해보죠
"access": {
"projects": [{
"projectId": ObjectId(...),
"milestones": [{
"milestoneId": ObjectId(...),
"pulses": [{
"pulseId": ObjectId(...)
}]
}]
}]
}
프로젝트 내부에 존재하는 마일스톤에 펄스를 추가하려면
db.users.updateOne({
"_id": ObjectId(userId)
}, {
"$push": {
"access.projects.$[i].milestones.$[j].pulses": ObjectId(pulseId)
}
}, {
arrayFilters: [{
"i.projectId": ObjectId(projectId)
}, {
"j.milestoneId": ObjectId(milestoneId)
}]
})
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)
}])
또한.
각 배열 필터는 단일 필드 이름을 가진 문서에 대한 술어여야 합니다.각 어레이 필터는 업데이트 식에 사용되어야 하며 각 어레이 필터 식별자 $[]에는 해당하는 어레이 필터가 있어야 합니다. 는 소문자로 시작하고 특수 문자를 포함하지 않아야 합니다.동일한 필드 이름을 가진 두 개의 배열 필터가 있으면 안 됩니다.
https://jira.mongodb.org/browse/SERVER-831
Mongo 3.6만 있으면 됩니다! 데이터베이스를 재설계하는 대신 Mongo 3.6의 어레이 필터 기능을 사용할 수 있습니다. 이 기능은 다음과 같습니다.
https://thecodebarbarian.com/a-nodejs-perspective-on-mongodb-36-array-filters
배열의 모든 일치 항목을 변수에 바인딩한 다음 나중에 해당 변수를 참조할 수 있습니다.다음은 위 링크의 주요 예입니다.
위치 연산자는 쿼리에서 한 번만 사용할 수 있습니다.이것은 제한 사항입니다. 개선을 위한 공개 티켓이 있습니다. https://jira.mongodb.org/browse/SERVER-831
언급한 바와 같이 현재 둘 이상의 위치 요소가 지원되지 않습니다.각() 메서드에 대해 mongodb 커서를 사용하여 업데이트할 수 있습니다.
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.$[i].comments.$.name': 'joe'
}},
{arrayFilters: [ { "i.comments.name": { $eq: 'jeff' } } ]}
)
answers
for get key path right
어레이 업데이트 시 성능에 큰 영향을 미치는 어레이와 동일한 문제가 발생했습니다.그래서 몽고드는 그것을 지원하지 않습니다.아래 지정된 링크에 표시된 대로 데이터베이스를 다시 설계합니다.
https://pythonolyk.wordpress.com/2016/01/17/mongodb-update-nested-array-using-positional-operator/
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 }
)
언급URL : https://stackoverflow.com/questions/24046470/mongodb-too-many-positional-i-e-elements-found-in-path
'sourcecode' 카테고리의 다른 글
devtools 패키지 설치 문제 (0) | 2023.06.28 |
---|---|
SQL Server에서 서로 다른 데이터 집합을 가진 두 데이터베이스에서 조인을 수행하고 오류가 발생하는 경우 (0) | 2023.06.23 |
roxygen2를 사용하여 예제를 실행하지 않는 방법은 무엇입니까? (0) | 2023.06.23 |
메서드 이름 끝에 있는 물음표는 루비에서 무엇을 의미합니까? (0) | 2023.06.23 |
Express + MongoDB를 위한 최고의 세션 스토리지 미들웨어 (0) | 2023.06.23 |