当我尝试创建子对象时,MongoDB将创建父对象 [英] MongoDB creates parent objects when I try to create child objects

查看:104
本文介绍了当我尝试创建子对象时,MongoDB将创建父对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此模型:

class SimCustomer < Customer
  index({ user_id: 1 },       { background: true })
  belongs_to :user,           :inverse_of => :sim_customers
end

此模型的继承:

class Customer
  include Mongoid::Document
  include Mongoid::Timestamps
  field :mail_address,        type: String
end

我从终端创建索引:

bundle exec rake db:mongoid:create_indexes

但是这会在Customer而不是SimCustomer上创建索引:

But this creates indexes on the Customer instead of the SimCustomer:

I, [2014-11-13T16:21:17.210343 #11407]  INFO -- : MONGOID: Created indexes on Customer:
I, [2014-11-13T16:21:17.210381 #11407]  INFO -- : MONGOID: Index: {:user_id=>1}, Options: {:background=>true}

当我尝试批量插入SimCustomer对象时,它会创建Customer对象:

And when I try to batch insert SimCustomer objects it creates Customer objects instead:

SimCustomer.collection.insert(Array.new << {mail_address: "hello@hello.com", user_id: "54652f5b43687229b4060000"})
# => #<Customer _id: 54654b7b6220ff4f28364ee9, created_at: nil, updated_at: nil, mail_address: "hello@hello.com", _type: "Customer">

我该如何解决?

推荐答案

这将设置Single Collection继承:

This sets up Single Collection Inheritance:

class SimCustomer < Customer

这意味着CustomerSimCustomer都将存储在MongoDB的customers集合中,并且将使用_type字段进行区分.

That means that both Customer and SimCustomer will be stored in the customers collection inside MongoDB and they'll be differentiated using the _type field.

SimCustomer中指定索引:

class SimCustomer < Customer
  index({ user_id: 1 },       { background: true })

将在customers集合上创建索引,因为这是SimCustomer的存储位置.

will create the index on the customers collection because that's where SimCustomers are stored.

同一收藏家的骗子导致您的大容量插入物出现问题.如果查看SimCustomer.collection.name,您会发现它显示'customers',因此,当然SimCustomer.collection.insert将创建新的Customer.如果要手动创建SimCustomer,请指定_type:

The same collection chicanery is causing your problem with your bulk insert. If you look at SimCustomer.collection.name you'll find that it says 'customers' so of course SimCustomer.collection.insert will create new Customers. If you want to create SimCustomers by hand then specify the _type:

SimCustomer.collection.insert(
  _type: 'SimCustomer',
  mail_address: "hello@hello.com",
  user_id: "54652f5b43687229b4060000"
)

请注意,我放下了看起来很奇怪的Array.new <<东西,我不知道您从哪里学到的,但是在对象上插入对象和奇怪的外观(如果要插入多个对象)是不必要的,如果要插入多个对象则只是使用数组文字:

Note that I dropped that strange looking Array.new << stuff, I don't know where you learned that from but it is unnecessary when inserting on object and odd looking if you were inserting several, if you want to insert several then just use an array literal:

SimCustomer.collection.insert([
  { ... },
  { ... },
  ...
])

您的下一个问题将是user_id中的字符串.那确实应该是一个Moped::BSON::ObjectId,否则您将在数据库中最终得到一个字符串,这将使您的查询变得一团糟. Mongoid可能知道属性应该是什么类型,但是Moped和MongoDB都不会.您将改为使用Moped::BSON::ObjectId('54652f5b43687229b4060000').

Your next problem is going to be that string in user_id. That really should be a Moped::BSON::ObjectId or you'll end up with a string inside the database and that will make a mess of your queries. Mongoid may know what type a property should be but neither Moped nor MongoDB will. You'll want to use Moped::BSON::ObjectId('54652f5b43687229b4060000') instead.

这篇关于当我尝试创建子对象时,MongoDB将创建父对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆