0
class Address
    has_one :order
end

class Order
    index({address_id: 1, background: true})
    belongs_to :address
end

Order には常に address_id がありますが、Address は Order に関連付けられていなくても存在できます。order.address_id == address.id のような注文がないすべてのアドレスを見つけようとしています。これどうやってするの?

4

1 に答える 1

0

以下のテストでは、メソッド addresses_without_an_order が Rails/Mongoid を介して質問に答えます。それは簡単で簡単ですが、非効率的です。さらに理解を深めるために、より効率的なものが必要であると仮定します。1 対 1 の関係は、Order コレクションの外部キー参照 address_id を介して実装されます。したがって、Address コレクションに対する単純なクエリでは、質問に答えることができません。MongoDB は 2 つのコレクション間の結合を実装しません (シャーディングを優先するため、結合は放棄されます)。

MongoDB でより効率的に join に相当するものを取得するには、子を親に埋め込みます。メソッド addresses_without_a_contact は、埋め込みを使用して質問に答えるのがいかに簡単かを示しています。1 対 1 の関係の場合、埋め込みは簡単かつ明白であり、結合よりもはるかに高いパフォーマンスを発揮します。これがあなたの質問に答えることを願っています。

アプリ/モデル/アドレス.rb

class Address
  include Mongoid::Document
  has_one :order
  embeds_one :contact
end

アプリ/モデル/order.rb

class Order
  include Mongoid::Document
  index({address_id: 1}, {background: true})
  belongs_to :address
end

アプリ/モデル/contact.rb

class Contact
  include Mongoid::Document
  embedded_in :address
end

テスト/ユニット/アドレス_test.rb

require 'test_helper'

class AddressTest < ActiveSupport::TestCase
  def setup
    Address.delete_all
    Order.delete_all
    puts
  end
  test "0. mongoid version" do
    puts "Mongoid::VERSION:#{Mongoid::VERSION}\nMoped::VERSION:#{Moped::VERSION}"
  end
  def addresses_without_an_order
    Address.all.collect{|address| address.order == nil ? address : nil}.compact
  end
  def addresses_without_a_contact
    Address.where(:contact.exists => false).to_a
  end
  test "Address" do
    address = Address.create(street: "229 W 43rd Street, 5th FL", city: "New York", state: "NY", zip: "10036")
    assert_equal 1, Address.count
    puts "addresses_without_an_order: #{addresses_without_an_order.inspect}"
    puts "addresses_without_a_contact: #{addresses_without_a_contact.inspect}"
    address.order = Order.create(ASIN: "B00DUW4BMS", title: "The C++ Programming Language (4th Edition)", author: "Bjarne Stroustrup")
    address.contact = Contact.new(name: "Isabel")
    assert_equal 1, Order.count
    assert_equal [], addresses_without_an_order
    assert_equal [], addresses_without_a_contact
  end
end

$レーキテスト

Run options:

# Running tests:

[1/2] AddressTest#test_0._mongoid_version
Mongoid::VERSION:3.1.5
Moped::VERSION:1.5.1
[2/2] AddressTest#test_Address
addresses_without_an_order: [#<Address _id: 528a5fa37f11ba7227000001, street: "229 W 43rd Street, 5th FL", city: "New York", state: "NY", zip: "10036">]
addresses_without_a_contact: [#<Address _id: 528a5fa37f11ba7227000001, street: "229 W 43rd Street, 5th FL", city: "New York", state: "NY", zip: "10036">]
Finished tests in 0.054955s, 36.3934 tests/s, 72.7868 assertions/s.
2 tests, 4 assertions, 0 failures, 0 errors, 0 skips
于 2013-11-18T19:05:59.220 に答える