Php 如何在mongodb中更改集合结构?
我有一个mongodb系列,如Php 如何在mongodb中更改集合结构?,php,mongodb,collections,alter-table,Php,Mongodb,Collections,Alter Table,我有一个mongodb系列,如 { "_id" : 57, "value" : { "user" : [ { "fk_status_id" : "0", "firstname" : "Ajith", "lastname" : "S", "city" : "known", "State" :"kerala"
{
"_id" : 57,
"value" : {
"user" : [
{
"fk_status_id" : "0",
"firstname" : "Ajith",
"lastname" : "S",
"city" : "known",
"State" :"kerala",
"location" : {
"lat" : 34.123456,
"lon" : -95.123456
},
}
],
}}
拥有数百万文档
{
"_id" : 58,
"user" : [
{
"fk_status_id" : "0",
"firstname" : "Ajith",
"lastname" : "S",
"city" : "known",
"State" :"kerala",
"location" : {
"lat" : 34.123456,
"lon" : -95.123456
},
}
]}
我想像这样修改表结构
{
"_id" : 58,
"user" : [
{
"fk_status_id" : "0",
"firstname" : "Ajith",
"lastname" : "S",
"city" : "known",
"State" :"kerala",
"location" : {
"lat" : 34.123456,
"lon" : -95.123456
},
}
]}
我的意思是,我想从这个结构中省略'value{}'。
- 数据应该在“值”之外。 请解决我的问题
db.collection.find().forEach(function(doc) {
var user = doc.value.user;
delete doc.value;
db.collection.update(
{ "_id": doc._id },
{ "$set": { "user": user } }
);
})
这是基本的过程,对于大型数据集来说有点可怕
但是对于“一次性”转换,有一种方法可以做到这一点,尽管这不是一种很好的方法,它被称为db.eval()
方法。但请注意文档(手册页面的大翻页):
警告
- 默认情况下,db.eval()在计算JavaScript函数之前接受全局写锁。因此,在运行db.eval()操作时,db.eval()会阻止对数据库的所有其他读写操作。在eval命令上将nolock设置为true,以防止eval命令在评估JavaScript之前获取全局写锁。nolock不影响JavaScript代码本身中的操作是否具有写锁
- 不要将db.eval()用于长时间运行的操作,因为db.eval()会阻止所有其他操作。考虑使用.< /P>
- 不能对数据使用db.eval()。通常,应该避免在中使用db.eval();不过,可以将db.eval()用于存储在数据库中的非分片集合和数据库
- 启用身份验证后,如果您没有执行指定任务的权限,db.eval()将在操作期间失败
db.eval(function() {
db.collection.find().forEach(function(doc) {
var user = doc.value.user;
delete doc.value;
db.collection.update(
{ "_id": doc._id },
{ "$set": { "user": user } }
);
});
});
当然,正如所建议的那样,还有其他方法来实现这一点
- mapReduce可以在某种程度上做到这一点,而不存在锁定问题,但是输出仍然需要大量的重塑,以及集合重命名和替换
- 在服务器上实际运行(或在网络中最接近),这可能是最好的选择。通过这种方式,您可以安全地编码并避免扩展锁定问题
但是,如果您真的像以前那样“陷入困境”,那么服务器上的JavaScript执行将修复您需要的特定问题。您已经切分了吗?你能在数据库节点上直接连接到shell吗?不,它不是分片的