我有一个像"geo": [39.897867,-121.8909978]
在我的MongoDb集合数组。
我需要做的是交换数组中的值
请帮我一下。谢谢你…
可以使用数组索引进行交换。首先找到它并交换它。
db.myCollection.find().forEach(function(doc){
db.myCollection.update({_id: doc._id},
{$set: {"geo.0": doc.geo[1], "geo.1": doc.geo[0]}})
})
既然你似乎没有明显的迭代循环,你担心的是项目的数量,那么让我们看看你的选项:
mapReduce可以是一个选项。但请注意,您的文档格式可能会有所不同。因此,如果您可以在应用程序中重命名已使用的集合,那么这将是一种安全复制集合的方法。但如果你的收藏是定期更新的,这将不是一个选择。
db.collection.mapReduce(
function() {
var t = this.geo[0];
this.geo[0] = this.geo[1];
this.geo[1] = t;
emit( this._id, this );
},
function(){},
{
"out" : { "replace": "newcollection" }
}
)
然后你可以安全地用 db.eval()
和一个循环来"重塑"回原始形式:
db.eval(function(){
db.newcollection.find().forEach(function(doc) {
var newDoc = {};
Object.keys(doc.value).forEach(function(key) {
newDoc["key"] = doc.value["key"];
});
db.newcollection.update(doc._id,newDoc);
});
})
给你一个具有另一个名称的"固定"集合。你可以直接将你的应用程序指向它,但如果你不能,那么你可以使用重命名集合来完成这项工作:
db.collection.drop();
db.newcollection.rename("collection");
但是在整个过程中会有很多磁盘抖动,当然在任何情况下您都需要为集合重新创建索引。
也可以直接在现有的集合上选择 db.eval()
:
db.eval(function(){
db.collection.find().forEach(function(doc){
db.collection.update(
{_id: doc._id},
{"$set": {"geo.0": doc.geo[1], "geo.1": doc.geo[0]}}
);
});
})
但是请阅读关于这个的文档。在执行此操作时,无论如何都是在锁定数据库。还可以查看有关并发性的常见问题解答。
当然,最安全的做法是从客户端使用查找和更新循环,只要该客户端在网络方面尽可能靠近数据库服务器,那么它将有很多有线通信,但它将相当本地化。
在一天结束时,如果最安全的方法是不可能的(并且可能是由于您的数据库与外部托管提供商),那么您就只能在服务器上更新其他选项,或者最终只是通过有线通信。
但至少你有一些选择可以考虑