我有一个文档列表,每个文档都有lat和lon属性(等等).
{ '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视为字符串.如何引用文档的属性?
干杯.
更新:如果您只需更改文档的结构而不更改值,请参阅gipset的答案以获得更好的解决方案.
根据更新文档页面上的(现在不可用)注释,您无法从中引用当前文档的属性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()
根据您的需要,此类功能还可用于map-reduce作业或服务器端作业.
在$重命名操作(介绍这个问题被张贴一个月后),使得它很容易做这些事情,你并不需要修改的值.
插入一些测试文档
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" : [ ] }