首页 > 解决方案 > 如何使用 python mongodb 客户端库(pymongo)更新 mongodb 集合中所有文档的字段“类型”

问题描述

这是完成一个非常重要的数据管道的最后一个链接。我们有以下以换行符分隔的 JSON,我们已将其从 BigQuery 导出到 GCS,然后在本地下载:

{"name":"Terripins","fga":"42","fgm":"28","fgPct":0.67}
{"gameTime":"2019-01-12 12:00:00 UTC","gameDate":"2019-01-12","updated":"2019-01-12 20:25:03 UTC","isHome":true,"name":"","fga":"0","fgm":"0"}
{"gameTime":"2019-01-12 12:00:00 UTC","gameDate":"2019-01-12","updated":"2019-01-12 20:25:03 UTC","isHome":true,"name":"Crusaders","fga":"54","fgm":"33","fgPct":0.61}
{"gameTime":"2019-01-12 12:00:00 UTC","gameDate":"2019-01-12","updated":"2019-01-12 20:25:03 UTC","isHome":false,"name":"Greyhounds","fga":"54","fgm":"33","fgPct":0.61}
{"gameTime":"2019-01-12 12:00:00 UTC","gameDate":"2019-01-12","updated":"2019-01-12 20:25:03 UTC","isHome":false,"name":"Greyhounds","fga":"68","fgm":"20","fgPct":0.29}
{"gameTime":"2019-01-12 12:00:00 UTC","gameDate":"2019-01-12","updated":"2019-01-12 20:25:03 UTC","isHome":true,"name":"Crusaders","fga":"68","fgm":"20","fgPct":0.29}

我们mongoimport将其放入我们的 mongodb 集群,并成功创建集合:

在此处输入图像描述

不幸的是,当我们从 BigQuery 导出 JSON 时,整数类型被转换为字符串(请参阅fga, fgm),日期列也被转换为字符串。此图显示了 BigQuery 的原始架构。

在此处输入图像描述

我们正在尝试使用 python mongodb 客户端库pymongofga, 和fgm转换为整数类型。据推测,(a)将“字符串化”的json文件加载到mongodb中,然后使用pymongo更新类型,而不是(b)在进入mongo之前直接在JSON文件中更新或修复类型。 mongoimport所以我们正在尝试(a)。

import(pymongo)

... connect to db and set "db"
our_collection = db["our_coll_name"]

# query and set for "update"
myquery = {} # for whole table
newvalues = { "$set": { "fga": int(fga) } } # change to int

# and update
new_output = our_collection.update_many(myquery, newvalues)
print(new_output.modified_count, "documents updated."

这不起作用,因为int(fga)返回一个错误name 'fga' is not defined,如果我们改为运行int("fga"),就会得到错误ValueError: invalid literal for int() with base 10: 'fga'

这些错误对我们来说都是完全有意义的,但我们仍然不确定如何更新fgafgm在这个例子中是int. 此外,我们可以为 3 个字段使用特定于 mongo 的类型date和类型,我们如何使用 pymongo 进行这些转换?timestamp[gameTime, gameDate, updated]

标签: pythonmongodbtype-conversionpymongo

解决方案


假设 MongoDB 4.2 或更高版本。

使用 MongoDB 的toInt()toDate()函数。

为了清楚起见,我将它们分成单独的命令,但如果您愿意,可以在一个 update_many() 中运行它。

our_collection.update_many({}, [{'$set': {'fga': {'$toInt': '$fga'}}}])
our_collection.update_many({}, [{'$set': {'fgm': {'$toInt': '$fgm'}}}])
our_collection.update_many({}, [{'$set': {'gameTime': {'$toDate': '$gameTime'}}}])
our_collection.update_many({}, [{'$set': {'gameDate': {'$toDate': '$gameDate'}}}])
our_collection.update_many({}, [{'$set': {'updated': {'$toDate': '$updated'}}}])

文档:

https://docs.mongodb.com/manual/reference/operator/aggregation/toInt/ https://docs.mongodb.com/manual/reference/operator/aggregation/toDate/


推荐阅读