gpt4 book ai didi

php - 如何更改 mongodb 中的集合结构?

转载 作者:可可西里 更新时间:2023-11-01 09:59:12 25 4
gpt4 key购买 nike

我有一个像这样的 mongodb 集合

{
"_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
},
}

]}

我的意思是,我想从这个结构中省略“值{}”。

  • 数据应该在“值”之外。请解决我的问题。

最佳答案

好吧,您没有回答给出的评论,但由于将要解释的原因,它很重要。

因此,如果您现在确实有“数以百万计的文档”必须更改并快速执行此操作,那么您将面临一个明显的问题。由于没有“原子”操作可以通过“引用”现有字段中的值来对文档进行操作以应用于更新,因此唯一的方法是实际循环结果:

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() 方法。但请注意文档(手册页中的 Big Rip):

WARNING

  • By default, db.eval() takes a global write lock before evaluating the JavaScript function. As a result, db.eval() blocks all other read and write operations to the database while the db.eval() operation runs. Set nolock to true on the eval command to prevent the eval command from taking the global write lock before evaluating the JavaScript. nolock does not impact whether operations within the JavaScript code itself takes a write lock.

  • Do not use db.eval() for long running operations as db.eval() blocks all other operations. Consider using other server side code execution options.

  • You can not use db.eval() with sharded data. In general, you should avoid using db.eval() in sharded cluster; nevertheless, it is possible to use db.eval() with non-sharded collections and databases stored in a sharded cluster.

  • With authentication enabled, db.eval() will fail during the operation if you do not have the permission to perform a specified task.

Changed in version 2.4: You must have full admin access to run.

有了这个,如果这确实符合您的情况,那么我们就不必像鸵鸟一样(并将我们的头埋在沙子“神话”中)并实际做一些可以在服务器上运行的东西来做到这一点:

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 可以在没有锁定问题的情况下做到这一点,但输出仍然需要大量的 reshape 以及集合重命名和替换。

  • 实际在服务器(或网络术语中最接近的服务器)上运行,这可能是最好的选择。通过这种方式,您可以安全地编码并避免扩展锁定问题。

但如果您确实“陷入困境”,服务器上的 JavaScript 执行将解决该特定问题(如果您需要的话)。

关于php - 如何更改 mongodb 中的集合结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23124679/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com