복붙노트

[MONGODB] Mongoid와 MongoDB를과의 관계를 통해 어떻게 has_many를 구현하는 방법?

MONGODB

Mongoid와 MongoDB를과의 관계를 통해 어떻게 has_many를 구현하는 방법?

레일 가이드에서이 변형 예를 사용하는 방법을 하나 개의 모델 관계형 "has_many : 통해"않습니다 협회는 mongoid를 사용하고 계십니까?

문제는 mongoid이 아닌 지원 has_many을 수행한다는 것입니다 : 액티브는 마찬가지로 통해.

# doctor checking out patient
class Physician < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
  has_many :meeting_notes, :through => :appointments
end

# notes taken during the appointment
class MeetingNote < ActiveRecord::Base
  has_many :appointments
  has_many :patients, :through => :appointments
  has_many :physicians, :through => :appointments
end

# the patient
class Patient < ActiveRecord::Base
  has_many :appointments
  has_many :physicians, :through => :appointments
  has_many :meeting_notes, :through => :appointments
end

# the appointment
class Appointment < ActiveRecord::Base
  belongs_to :physician
  belongs_to :patient
  belongs_to :meeting_note
  # has timestamp attribute
end

해결법

  1. ==============================

    1.을 통해 또는 동등한 기능 : Mongoid은 has_many이 없습니다. 당신이 아직도 여러 쿼리를 필요로 다른 통해 관련 모음을 참조 할 수 있다면 너무도 쿼리에 가입 지원하지 않기 때문에 그것은 MongoDB를 너무 유용하지 않을 것입니다.

    을 통해 또는 동등한 기능 : Mongoid은 has_many이 없습니다. 당신이 아직도 여러 쿼리를 필요로 다른 통해 관련 모음을 참조 할 수 있다면 너무도 쿼리에 가입 지원하지 않기 때문에 그것은 MongoDB를 너무 유용하지 않을 것입니다.

    https://github.com/mongoid/mongoid/issues/544

    당신이 RDBMS에 많은 많은 관계가있는 경우 보통은 양쪽에 '외국'키의 배열을 포함하는 필드를 사용하여 MongoDB를 다르게 그 모델 것입니다. 예를 들면 :

    class Physician
      include Mongoid::Document
      has_and_belongs_to_many :patients
    end
    
    class Patient
      include Mongoid::Document
      has_and_belongs_to_many :physicians
    end
    

    즉 당신은 테이블을 조인 제거하는 것입니다 그것은 has_many와 비슷한 효과를 것 다음 '다른 쪽'에 대한 접근의 측면에서 통해. 당신의 가입 테이블이 몇 가지 추가 정보뿐 아니라 협회를 전달하는 예약 클래스이기 때문에 그러나 귀하의 경우에 그게 아마 적절하지.

    당신이 모델을 어떻게 당신이 실행해야하는 쿼리에 어느 정도 의존하지만이 같은 환자 및 의사 뭔가 연결을 약속 모델을 추가하고 정의해야합니다 것처럼 보인다

    class Physician
      include Mongoid::Document
      has_many :appointments
    end
    
    class Appointment
      include Mongoid::Document
      belongs_to :physician
      belongs_to :patient
    end
    
    class Patient
      include Mongoid::Document
      has_many :appointments
    end
    

    MongoDB의의 관계로 항상 포함 또는 관련 문서 사이에서 선택을해야합니다. 모델에서 나는 MeetingNotes이 포함 된 관계에 대한 좋은 후보입니다 추측 것입니다.

    class Appointment
      include Mongoid::Document
      embeds_many :meeting_notes
    end
    
    class MeetingNote
      include Mongoid::Document
      embedded_in :appointment
    end
    

    이 협회가 있다면 여러 쿼리를해야하는 반면이 방법은 당신이 모두 함께 약속과 함께 메모를 검색 할 수있다. 당신은 마음에 곰에 당신이 메모를 충족 매우 많은 경우 놀이로 올 수있는 하나의 문서에 대한 16 메가 바이트 크기 제한이 있습니다.

  2. ==============================

    2.액티브에서 통해 기록의 배열 대신 쿼리 프록시를 반환하여 : 그냥 여기에 has_many와 매우 유사 행동 방법과 확장 된 모델이다,이에 확장 :

    액티브에서 통해 기록의 배열 대신 쿼리 프록시를 반환하여 : 그냥 여기에 has_many와 매우 유사 행동 방법과 확장 된 모델이다,이에 확장 :

    class Physician
      include Mongoid::Document
      has_many :appointments
    
      def patients
        Patient.in(id: appointments.pluck(:patient_id))
      end
    end
    
    class Appointment
      include Mongoid::Document
      belongs_to :physician
      belongs_to :patient
    end
    
    class Patient
      include Mongoid::Document
      has_many :appointments
    
      def physicians
        Physician.in(id: appointments.pluck(:physician_id))
      end
    end
    
  3. ==============================

    3.스티븐 소로 카 솔루션은 정말 위대하다! 나는 (내가 새 응답 추가 해요 이유 있다고 : P)에 대한 답변을 의견을 명성이 없습니다 (당신의 has_many 관계가 hunders있는 경우 특별히 | 수천 개의 레코드)하지만 관계에 대한지도를 사용하여 생각이 비싼 그것을 가져 있기 때문에 데이터베이스로부터의 데이터는, 각 레코드를 구축 원의 배열을 생성하고, 지정된 블록의 값으로 새 구축 일본어 어레이를 통해 반복 할.

    스티븐 소로 카 솔루션은 정말 위대하다! 나는 (내가 새 응답 추가 해요 이유 있다고 : P)에 대한 답변을 의견을 명성이 없습니다 (당신의 has_many 관계가 hunders있는 경우 특별히 | 수천 개의 레코드)하지만 관계에 대한지도를 사용하여 생각이 비싼 그것을 가져 있기 때문에 데이터베이스로부터의 데이터는, 각 레코드를 구축 원의 배열을 생성하고, 지정된 블록의 값으로 새 구축 일본어 어레이를 통해 반복 할.

    뽑은를 사용하면 빠르고 어쩌면 가장 빠른 방법입니다.

    class Physician
      include Mongoid::Document
      has_many :appointments
    
      def patients
        Patient.in(id: appointments.pluck(:patient_id))
      end
    end
    
    class Appointment
      include Mongoid::Document
      belongs_to :physician
      belongs_to :patient 
    end
    
    class Patient
      include Mongoid::Document
      has_many :appointments 
    
      def physicians
        Physician.in(id: appointments.pluck(:physician_id))
      end
    end
    

    Benchmark.measure 일부 통계 여기 :

    > Benchmark.measure { physician.appointments.map(&:patient_id) }
     => #<Benchmark::Tms:0xb671654 @label="", @real=0.114643818, @cstime=0.0, @cutime=0.0, @stime=0.010000000000000009, @utime=0.06999999999999984, @total=0.07999999999999985> 
    
    > Benchmark.measure { physician.appointments.pluck(:patient_id) }
     => #<Benchmark::Tms:0xb6f4054 @label="", @real=0.033517774, @cstime=0.0, @cutime=0.0, @stime=0.0, @utime=0.0, @total=0.0> 
    

    난 그냥 250 약속을 사용하고 있습니다. patient_id과 :에 인덱스를 추가하는 것을 잊지 마세요 physician_id을 약속 문서에!

    나는 그것이 도움이되기를 바랍니다, 읽어 주셔서 감사합니다!

  4. ==============================

    4.관점을 통해 : 나는 자체 참조 관계의 관점 만이 아니라 has_many에서이 질문에 대답하고 싶다.

    관점을 통해 : 나는 자체 참조 관계의 관점 만이 아니라 has_many에서이 질문에 대답하고 싶다.

    하자 우리가 접촉을 가진 CRM을 말한다. 연락처가 다른 연락처와 관계를해야하지만 대신 두 개의 서로 다른 모델 사이의 관계를 만드는, 우리는 같은 모델의 두 인스턴스 사이의 관계를 생성 할 수 있습니다. 연락처는 많은 친구를 가질 수 있고 우리는 다 대다 관계를 만들어야 할 겁니다 많은 다른 연락처로 친구가 될 수있다.

    우리는 RDBMS와 액티브를 사용하는 경우, 우리는 has_many을 사용합니다 :을 통해. 따라서 우리는 우정과 같은 모델을 가입 만들어야합니다. 이 모델은 두 개의 필드, 친구를 추가하는 것 현재의 접촉을 나타내는 contact_id와 친구가되고있는 사용자를 나타내는 friend_id있을 것입니다.

    그러나 우리는 MongoDB를하고 Mongoid을 사용하고 있습니다. 을 통해 또는 동등한 기능 : 위에서 언급 한 바와 같이, Mongoid은 has_many이 없습니다. 이 쿼리에 가입 지원하지 않기 때문에 그것은 MongoDB를 너무 유용하지 않을 것입니다. 따라서, MongoDB를 같은 비 RDBMS 데이터베이스에 많은 많은 관계를 모델링하기 위해, 당신은 양쪽에 '외국'키의 배열을 포함하는 필드를 사용합니다.

    class Contact
      include Mongoid::Document
      has_and_belongs_to_many :practices
    end
    
    class Practice
      include Mongoid::Document
      has_and_belongs_to_many :contacts
    end
    

    문서 상태로 :

    # the contact document
    {
      "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
      "practice_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
    }
    
    # the practice document
    {
      "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
      "contact_ids" : [ ObjectId("4d3ed089fb60ab534684b7f2") ]
    }
    

    이제 MongoDB의에서 자체 참조 협회, 당신은 몇 가지 옵션이 있습니다.

    has_many :related_contacts, :class_name => 'Contact', :inverse_of => :parent_contact
    belongs_to :parent_contact, :class_name => 'Contact', :inverse_of => :related_contacts
    

    관련 연락처와 접촉을 많이 가진 많은 관행에 속하는 사이의 차이점은 무엇입니까? 큰 차이! 하나는 두 엔티티 사이의 관계이다. 기타 자기 참조입니다.

  5. from https://stackoverflow.com/questions/7000605/how-to-implement-has-many-through-relationships-with-mongoid-and-mongodb by cc-by-sa and MIT license