5

我正在尝试使用 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视为字符串?

不起作用的事情:

  • 用双双引号""0364""、双引号和单引号"'0364'"或'"0364"'包围数据
  • 将空字符串附加到值:{ "_id" : "0364" + "", someField: "value" }
4

5 回答 5

2

刚刚遇到同样的问题并发现了一个替代方案。您可以通过将 CSV 转换为 JSON 并引用该字段来强制 Mongo 将字符串类型用于非字符串值。例如,如果您的 CSV 如下所示:

key value
123 foo
abc bar

然后,您将获得键 123 的整数字段和键 abc 的字符串字段。如果您将其转换为 JSON,确保所有键都被引用,然后--type json在导入时使用,您最终会得到所需的行为:

{
    "123":"foo",
    "abc":"bar"
}
于 2013-08-01T17:43:34.540 回答
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)
于 2012-04-24T17:52:46.687 回答
1

我能够为数字字符串添加前缀,这对我有用。例子:

00012345 被导入为 12345(Int 类型)字符串00012345 被导入为 string00012345(字符串类型)

我的来源是一个 SQL 数据库,所以我只是做了

select 'string'+column as name

当然,你还需要做一些后处理来解析字符串,但比将一个相当大的 tsv 文件转换为 json 的工作量要少得多。

我还在上面的 jira 链接中添加了 +1 以进行增强。

于 2014-05-28T00:11:36.083 回答
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>
于 2016-10-16T13:49:30.587 回答
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
});
于 2016-08-31T15:31:18.930 回答