所以........我有一个rails应用程序。 rails应用程序使用Mongoid来获取mongodb数据。当我通过Web表单创建mongo记录时,它们具有类型为string
的ID。当我使用mongoimport将记录导入mongo时,他们的ID为BSON::ObjectId
。
rails应用程序期望mongo记录ID是字符串,因此当我导入数据时,它会导致我的应用程序失败,因为当它查找记录时它会抱怨它can't convert type BSON::ObjectId to string
我对这里的一些层面感到困惑。 BSON :: ObjectId是mongo中ID的默认类型,所以我不明白为什么通过rails和Mongoid创建的记录都有字符串ID。我没有看到Mongoid指定_id字段应该是字符串的任何地方。有没有人有任何线索?
答案 0 :(得分:2)
您使用的是什么版本的Mongoid?从这篇帖子看,看起来Mongoid在一年前使用字符串为_id,但现在一直使用BSON :: ObjectId类型。
mongodb: converting object ID's to BSON::ObjectId
它引用了这个要点,用于将使用String _id的旧文档转换为使用BSON :: ObjectId类型_id的。
当Mongoid将文档插入集合时,它期望并使用BSON :: ObjectId类型。这是使用Rails控制台的示例:
post = Post.new => # post.save =>真正 post._id => BSON ::的ObjectId( '4ff5bcb39ef1728393000002') post._id.class => BSON ::的ObjectId
Mongoid似乎知道使用BSON :: ObjectId类型查找_id:
Post.where(:_ id =>“4ff5bcb39ef1728393000002”)。count => 1
Post.where(:_ id => BSON :: ObjectId(“4ff5bcb39ef1728393000002”))。count => 1
您是否有机会手动设置_id?如果你是,那么也许你没有将_id设置为BSON :: ObjectId类型。
答案 1 :(得分:0)
关于你的最后一段:MongoDB的specification期待12字节字符串。
答案 2 :(得分:0)
所以我明白了。问题在于我的应用程序使用的Mongoid版本。版本1.9.5使用字符串作为_id字段的默认类型,这正是我正在使用的。
我考虑过更新Mongoid,但我担心旧的字符串ID会以某种方式破坏应用程序。
答案是以某种方式使用rails app导入记录,以便旧版本的Mongoid负责插入记录。我创建了一个rake任务,该任务将解析CSV文件并在我的应用程序环境中插入该文件中的记录。
require 'csv'
require 'iconv'
namespace :deadline do
desc "Import data from CSV file"
task :import => :environment do
CSV.parse(File.open("/tmp/deadlines.csv").read).map{ |row|
app_deadline = OrgSpecific::ApplicationDeadline.create!(
:name => row[2] + " " + row[3],
:start_date => Date.strptime('1/1/2012', '%m/%d/%Y'),
:deadline_date => Date.strptime(row[11], '%m/%d/%Y'),
:term => row[2],
:year => row[3],
:comment => Iconv.conv("UTF8", "LATIN1", row[5]) + " : " + Iconv.conv("UTF8", "LATIN1", row[6])
)
}
end
end
瞧!我的CSV文件中的所有数据都是通过我的rails环境导入的,这意味着我的mongo记录的字符串类型为_id。谢谢你的帮助!