【问题标题】:Find and Replace NumberLong type field in mongodb在 mongodb 中查找和替换 NumberLong 类型字段
【发布时间】:2015-09-09 07:26:18
【问题描述】:

我正在尝试用其他 NumberLong 值更新我的一个集合中的某个 NumberLong 类型值。以下是我的收藏结构:

    {
    "_id" : ObjectId("55e57337d4c6cf80e68b1fe3"),
    "tenantId" : NumberLong(7),
    "refId" : NumberLong(20),
    "refIdentifierName" : "resourceInstanceId",
    "config" : {
        "contract" : {
            "contractLength" : "12 months",
            "startDate" : "2015-01-21T09:36:39+00:00",
            "billingFrequency" : "monthly",
            "margin" : 9,
            "endDate" : "2016-01-21T09:36:39+00:00"
        }

}

假设我正在尝试将所有值为 7 的tenantId 更新为 8。

这是我正在使用的脚本:

 var cursor = db.resourceInstanceConfiguration.find();
while (cursor.hasNext()) {
  var x = cursor.next();
  x['tenantId'] = x['tenantId'].replace('7','8');
  db.resourceInstanceConfiguration.update({_id : x._id}, x);
}

收到错误:TypeError: Object NumberLong(6) has no method 'replace'

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    您可以使用以下查询来实现此目的:

    db.collection.update(
       <query>,
       <update>,
       {
         upsert: <boolean>,
         multi: <boolean>,
         writeConcern: <document>
       }
    )
    
    db.collectionName.update({<field>:<value>},{$set:{<field>:<New Value>}},<upsert>,<multi>);
    

    【讨论】:

    • 如果我是你,我会为投票感到幸运,因为这实际上只不过是选项文档中的列表,也是对所提问题的完全错误答案。
    • 好吧..这行得通! db.resourceInstanceConfiguration.update({"tenantId":NumberLong(7)},{$set:{"tenantId":NumberLong(8)}},false,true)
    【解决方案2】:

    似乎有些人很快就支持另一个答案,却没有意识到它不可能起作用,也不是一个很好的解释。

    这里的两个问题是您基本上需要“循环”结果以读取您想要更改的值,然后将它们写回。这可能最好使用 "Bulk" operations 处理,最好在 shell 下作为脚本之一完成。

    “下一个”问题是这里的 BSON 类型信息是“粘性”的,您不能简单地将值更改为代码中的普通双精度值并将其写回。您实际上需要从文档中完全“删除”该字段,然后才能写回转换后的值。

    整个过程同样适用于批量操作,如下所示:

    var bulk = db.resourceInstanceConfiguration.initializeOrderedBulkOp(),
        count = 0;
    
    db.junk.find({ 
        "$or": [
            { "tenantId": { "$type": 18 } },
            { "refId": { "$type": 18 } }
        ]            
    }).forEach(function(doc) {
        print(doc.a.valueOf());
        bulk.find({ "_id": doc._id }).updateOne({
            "$unset": { "tenantId": "", "refId": "" }
        });
        bulk.find({ "_id": doc._id }).updateOne({
            "$set": { 
                "tenantId": doc.tenantId.valueOf(),
                "refId": doc.tenantId.valueOf()
            }
        });
        count += 2;
    
        if ( count % 1000 == 0 ) {
            bulk.execute();
            bulk = db.resourceInstanceConfiguration.initializeOrderedBulkOp();
        }
    
    });
    
    if ( count % 1000 != 0 )
        bulk.execute();
    

    因此,您基本上是 $unset 首先删除该字段的 BSON 数据的所有跟踪以及具有新值的 $set

    所有值都将是标准的“double”或 BSON 类型 1,这也由 $type 运算符确认。

    【讨论】:

    • 嘿,感谢您的准确解释,尽管 Kartikey 给出的答案对我有用!试过这个:db.resourceInstanceEvent.update({"refId":NumberLong(7)},{$set:{"refId":NumberLong(8)}},false,true);
    • @RahulBGangwar 好吧,如果您只想用标准数字“替换所有内容”,那么它将起作用。猜猜这确实是对您的问题的误读,因为人们确实会问NumberIntDouble 此处显示的内容,但我仍然说仅引用文档是回答问题的恶劣借口。就我个人而言,我不会鼓励某人使用搜索引擎。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 2017-07-22
    • 2011-02-08
    • 2018-02-16
    • 1970-01-01
    • 2013-04-04
    • 2011-02-21
    相关资源
    最近更新 更多