使用update更改mongodb中对象的模式

时间:2014-05-05 19:31:09

标签: mongodb

我从一个巨大的ms excel表格表中导入了csv。所以这个系列是一个层次。我需要更改一些列,因此它们是2级。

示例,这是来自csv-import。

{
  title: 'House A',
  energyElectricity: 55,
  energyHeat: 35, 
  energyCooling:45
}

这不好。我想用以下格式:

  {
    title: 'House A',
    energy: {
     electricity: 55,
     heat: 35,
     cooling:45
    }
  }

是否有更新查询执行此操作?

我尝试了一些东西,但没有运气。 这里有一些伪代码:

db.consumers.update({},{energy.electricity:energyElectricity,energy.heat:energyHeat},{multi:true});

1 个答案:

答案 0 :(得分:0)

除了循环结果之外,没有其他方法可以做到这一点,因为在更新操作期间目前无法引用文档的任何现有字段。

所以你的基本结构需要看起来像(用任何语言):

db.collection.find({}).forEach(function(doc) {
    db.collection.update(
        { "_id": doc._id },
        {
            "title": doc.title,
            "energy": {
               "electricity": doc.energyElectricty,
               "heat": doc.energyHeat,
               "cooling": doc.energyCooling
            }
        }
    );

});

您可以使用MongoDB 2.6及更高版本提供的"bulk updates"更高效地执行此操作:

var batch = [];
var count = 0;

db.collection.find({}).forEach(function(doc) {

    batch.push({
        "q": { "_id": doc._id },
        "u": {
            "title": doc.title,
            "energy": {
               "electricity": doc.energyElectricty,
               "heat": doc.energyHeat,
               "cooling": doc.energyCooling
            }
        }
    });
    count++;

    if ( count % 500 == 0 ) {
        db.runCommand({ "update": "collection", "updates": batch });
        batch = [];
    }

});

if ( batch.length > 0 ) {
    db.runCommand({ "update": "collection", "updates": batch });
}

因此,虽然所有更新仍然通过电线完成,但实际上这实际上只通过电线每500发送一次(或者您感觉舒适地坐在16MB BSON限制之下)。

当然,既然你提到这是来自CSV导入,你总是可以重新塑造你的输入并再次导入集合,如果这是一个合理的选择。