我正在尝试使用mongoimport在_id中使用字符串值来插入数据。 由于id看起来像整数(即使它们在引号中),mongoimport将它们视为整数并创建新记录而不是插入现有记录。
命令我正在运行:
mongoimport --host localhost --db database --collection my_collection --type csv --file mydata.csv --headerline --upsert
mydata.csv中的示例数据:
{ "_id" : "0364", someField: "value" }
结果将是mongo插入如下记录:{ "_id" : 364, someField: "value" }
而不是使用_id "0364"
更新记录。
是否有人知道如何将_id
视为字符串?
不起作用的事情:
{ "_id" : "0364" + "", someField: "value" }
答案 0 :(得分:2)
不幸的是,现在没有办法强制将类似数字的字符串解释为字符串:
https://jira.mongodb.org/browse/SERVER-3731
你可以用Python编写一个脚本或者其他一些你喜欢的语言:
import csv, pymongo
connection = pymongo.Connection()
collection = connection.mydatabase.mycollection
reader = csv.DictReader(open('myfile.csv'))
for line in reader:
print '_id', line['_id']
upsert_fields = {
'_id': line['_id'],
'my_other_upsert_field': line['my_other_upsert_field']}
collection.update(upsert_fields, line, upsert=True, safe=True)
答案 1 :(得分:2)
刚遇到同样的问题并发现了另一种选择。您可以通过将CSV转换为JSON并引用该字段来强制Mongo将字符串类型用于非字符串值。例如,如果您的CSV如下所示:
key value
123 foo
abc bar
然后,您将获得键123的整数字段和键abc的字符串字段。如果将其转换为JSON,确保引用所有键,然后在导入时使用--type json
,则最终会得到所需的行为:
{
"123":"foo",
"abc":"bar"
}
答案 2 :(得分:1)
我能够为数字字符串添加前缀,这对我有用。例如:
00012345导入为12345(类型Int) string00012345导入为string00012345(类型字符串)
我的来源是一个SQL数据库所以我刚刚做了
select 'string'+column as name
当然,你还需要做一些后处理来解析字符串,但是比将一个相当大的tsv文件转换为json要少得多。
我还在上面的jira链接中添加了+1以进行增强。
答案 3 :(得分:0)
作为@Jesse的替代品,您可以在mongo控制台中执行类似的操作,例如
db.my_collection.find().forEach(function (obj) {
db.my_collection.remove({_id: obj._id); // remove the old one
obj._id = '' + obj._id; // change to string
db.my_collection.save(obj); // resave
});
对于非_id
字段,您只需执行以下操作:
db.my_collection.find().forEach(function (obj) {
obj.someField = '' + obj.someField; // change to string
db.my_collection.save(obj); // resave
});
答案 4 :(得分:0)
我遇到了同样的问题。
我觉得最简单的方法是使用在线工具 将CSV文件转换为JSON文件,然后导入。
这是我使用的工具:
<强> http://www.convertcsv.com/csv-to-json.htm 强>
它允许您将CSV文件的整数值用双引号包装为JSON文件。
如果您在导入此JSON文件时遇到问题并遇到错误,只需将--jsonArray添加到您的导入命令即可。它肯定会起作用。
mongoimport --host localhost --db mydb -c mycollection --type json --jsonArray --file <file_path>