MongoDB : 동일한 문서의 데이터를 사용하여 문서 업데이트
이 질문에 이미 답변이 있습니다.
각각 위도 및 경도 속성이있는 문서 목록이 있습니다.
{ 'lat': 1, 'lon': 2, someotherdata [...] }
{ 'lat': 4, 'lon': 1, someotherdata [...] }
[...]
다음과 같이 수정하고 싶습니다.
{ 'coords': {'lat': 1, 'lon': 2}, someotherdata [...]}
{ 'coords': {'lat': 4, 'lon': 1}, someotherdata [...]}
[...]
지금까지 나는 이것을 얻었다 :
db.events.update({}, {$set : {'coords': {'lat': db.events.lat, 'lon': db.events.lon}}}, false, true)
그러나 db.events.lat 및 db.events.lon 을 문자열로 취급합니다 . 문서의 속성을 어떻게 참조 할 수 있습니까?
건배.
$ 이름 바꾸기 연산자 (도입이 질문을 게시 한 후 한 달)는 값을 수정할 필요가 없습니다 사물의 이러한 종류의 작업을 수행하는 정말 쉽습니다을한다.
테스트 문서 삽입
db.events.insert({ 'lat': 1, 'lon': 2, someotherdata: [] })
db.events.insert({ 'lat': 4, 'lon': 1, someotherdata: [] })
$rename연산자 사용
db.events.update({}, {$rename: {'lat': 'coords.lat', 'lon': 'coords.lon'}}, false, true)
결과
db.events.find()
{
"_id" : ObjectId("5113c82dd28c4e8b79971add"),
"coords" : {
"lat" : 1,
"lon" : 2
},
"someotherdata" : [ ]
}
{
"_id" : ObjectId("5113c82ed28c4e8b79971ade"),
"coords" : {
"lat" : 4,
"lon" : 1
},
"someotherdata" : [ ]
}
업데이트 : 값을 변경하지 않고 문서의 구조를 변경하기 만하면 좋은 솔루션에 대한 gipset의 답변 을 참조하십시오 .
문서 업데이트 페이지 의 (현재 사용할 수 없음) 주석에 따르면 .NET Framework에서 현재 문서의 속성을 참조 할 수 없습니다 update().
모든 문서를 반복하고 다음과 같이 업데이트해야합니다.
db.events.find().snapshot().forEach(
function (e) {
// update document, using its own properties
e.coords = { lat: e.lat, lon: e.lon };
// remove old properties
delete e.lat;
delete e.lon;
// save the updated document
db.events.save(e);
}
)
이러한 기능은 필요에 따라 맵 축소 작업 또는 서버 측 db.eval()작업 에서도 사용할 수 있습니다 .
Mongo 스크립트를 사용하여 데이터를 즉시 조작 할 수 있습니다. 그것은 나를 위해 작동합니다!
이 스크립트를 사용하여 주소 데이터를 수정합니다.
현재 주소의 예 : "No.12, FIFTH AVENUE,".
I want to remove the last redundant comma, the expected new address ""No.12, FIFTH AVENUE".
var cursor = db.myCollection.find().limit(100);
while (cursor.hasNext()) {
var currentDocument = cursor.next();
var address = currentDocument['address'];
var lastPosition = address.length - 1;
var lastChar = address.charAt(lastPosition);
if (lastChar == ",") {
var newAddress = address.slice(0, lastPosition);
currentDocument['address'] = newAddress;
db.localbizs.update({_id: currentDocument._id}, currentDocument);
}
}
Hope this helps!
As long as you are OK with creating a copy of the data, the aggregation framework can be used as an alternative here. You also have the option to do more to the data if you wish using other operators, but the only one you need is $project. It's somewhat wasteful in terms of space, but may be faster and more appropriate for some uses. To illustrate, I'll first insert some sample data into the foo collection:
db.foo.insert({ 'lat': 1, 'lon': 2, someotherdata : [1, 2, 3] })
db.foo.insert({ 'lat': 4, 'lon': 1, someotherdata : [4, 5, 6] })
Now, we just use $project to rework the lat and lon fields, then send them to the newfoo collection:
db.foo.aggregate([
{$project : {_id : "$_id", "coords.lat" : "$lat", "coords.lon" : "$lon", "someotherdata" : "$someotherdata" }},
{ $out : "newfoo" }
])
Then check newfoo for our altered data:
db.newfoo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
Once you are happy with the new data, you can then use the renameCollection() command to drop the old data and use the new data under the old name:
> db.newfoo.renameCollection("foo", true)
{ "ok" : 1 }
> db.foo.find()
{ "_id" : ObjectId("544548a71b5cf91c4893eb9a"), "someotherdata" : [ 1, 2, 3 ], "coords" : { "lat" : 1, "lon" : 2 } }
{ "_id" : ObjectId("544548a81b5cf91c4893eb9b"), "someotherdata" : [ 4, 5, 6 ], "coords" : { "lat" : 4, "lon" : 1 } }
One last note - until SERVER-7944 is completed you can't do the equivalent of a snapshot by hinting the _id index as suggested in this answer and so you can end up hitting a document more than once if activity elsewhere causes it to move. Since you are inserting the _id field in this example, any such occurrence would cause a unique key violation, so you will not end up with dupes, but you might have an "old" version of a document. As always, check your data thoroughly before dropping it, and preferably take a backup.
Neils answer. Just to let people know you cannot run this on a large database if you are lets say doing it remote shell like Robomongo. You will need to ssh into your actual server's mongo shell. Also you could also do this if you would rather do an Update.
db.Collection.find({***/ possible query /***}).toArray().forEach(
function(obj){
obj.item = obj.copiedItem;
obj.otherItem = obj.copiedItem;
obj.thirdItem = true;
obj.fourthItem = "string";
db.Collection.update({_id: obj._id}, obj);
}
);
From the CLI? I think you have to pull the values out first and assign the value into a variable. Then run your update command.
Or (I haven't tried) remove 'db' from the string. events.lat and events.lon If it works, you will still have multiple values, the old values for "lat" and "lon" and the new array you created.
'developer tip' 카테고리의 다른 글
| Angular2 * ngIf는 템플릿에서 객체 배열 길이를 확인합니다. (0) | 2020.10.20 |
|---|---|
| Python range ()와 유사한 JavaScript 함수 (0) | 2020.10.20 |
| 아이콘과 텍스트가있는 Android 버튼 (0) | 2020.10.20 |
| iOS-UIImageView-UIImage 이미지 방향 처리 방법 (0) | 2020.10.20 |
| MySQL의 자연 정렬 (0) | 2020.10.20 |