কীভাবে has_many প্রয়োগ করবেন: মংগয়েড এবং মংডোবের সাথে সম্পর্কের মাধ্যমে?


96

রেল গাইডগুলি থেকে এই পরিবর্তিত উদাহরণটি ব্যবহার করে , কীভাবে একটি মডেল সম্পর্কযুক্ত "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

উত্তর:


151

মঙ্গয়েডের হাতে_মানি নেই: মাধ্যমে বা সমতুল্য বৈশিষ্ট্য। এটি মঙ্গোডিবি-তে এতটা কার্যকর হবে না কারণ এটি যোগ করা প্রশ্নের সাথে সমর্থন করে না তাই এমনকি যদি আপনি অন্যের মাধ্যমে সম্পর্কিত সংগ্রহটি উল্লেখ করতে পারেন তবে এটিতে একাধিক প্রশ্নের প্রয়োজন পড়বে।

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

সাধারণত যদি কোনও আরডিবিএমএসে আপনার অনেকগুলি সম্পর্ক থাকে তবে আপনি মঙ্গোডিবিতে অন্যদিকে 'বিদেশী' কীগুলির একটি অ্যারে যুক্ত ক্ষেত্রটি ব্যবহার করে আলাদাভাবে মডেল করবেন। উদাহরণ স্বরূপ:

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

মঙ্গোডিবি-র সম্পর্কের সাথে আপনাকে সর্বদা এমবেডড বা সম্পর্কিত নথিগুলির মধ্যে একটি পছন্দ করতে হবে। আপনার মডেলটিতে আমি অনুমান করব যে মিলনোটোটস এম্বেড থাকা সম্পর্কের জন্য ভাল প্রার্থী।

class Appointment
  include Mongoid::Document
  embeds_many :meeting_notes
end

class MeetingNote
  include Mongoid::Document
  embedded_in :appointment
end

এর অর্থ হ'ল আপনি সমস্ত একসাথে একটি অ্যাপয়েন্টমেন্টের সাথে নোটগুলি পুনরুদ্ধার করতে পারেন, যদিও এটি যদি কোনও সমিতি হয় তবে আপনার একাধিক প্রশ্নের প্রয়োজন হবে। আপনাকে কেবলমাত্র একটি একক দস্তাবেজের জন্য 16 এমবি আকারের সীমা মনে রাখতে হবে যা আপনার কাছে খুব বেশি সংখ্যক বৈঠকের নোট থাকলে তা কার্যকর হতে পারে।


7
+1 খুব সুন্দর উত্তর, কেবল তথ্যের জন্য, মঙ্গডব আকারের সীমা 16 এমবি করা হয়েছে।
ঘষুন

4
কৌতূহলের বাইরে (দেরিতে তদন্তের জন্য দুঃখিত) আমি মঙ্গয়েডেও নতুন হয়েছি এবং আমি ভাবছিলাম যে সমিতিটি সংরক্ষণের জন্য আলাদা সংগ্রহ ব্যবহার করে কোনও এনএন সম্পর্ক করার সময় আপনি কীভাবে ডেটা অনুসন্ধান করবেন এটি কি একইরকম? অ্যাক্টিভেকর্ডের সাথে?
ইন্নোস্পার্ক

38

কেবল এটিকে প্রসারিত করার জন্য, এখানে মডেলগুলি এমন পদ্ধতিগুলির সাথে প্রসারিত করা হয়েছে যা 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

4
এটি অবশ্যই পুনরুদ্ধারের জন্য আমার পদ্ধতিটিকে এমন একটি অ্যারে ফিরিয়েছিল যা পৃষ্ঠাগুলি বিশৃঙ্খলা করেছিল cause
prasad.surase

4
কোন যাদু নেই। @ সিরিলডিডি, আপনি কী উল্লেখ করছেন? মানচিত্র (এবং: চিকিত্সক_আইডি) মানচিত্রের জন্য স্বল্প হাত {| অ্যাপয়েন্টমেন্ট | অ্যাপয়েন্টমেন্ট.ফিজিশিয়ান.আইডি}
স্টিভেন সোরোকা

আমি অবাক হই, এই নথিটি কীভাবে 16MBs নথি আকারের সীমা দিয়ে সম্ভাব্য হতাশাগুলি হ্রাস করবে, এটি প্রমাণিত করে যে নথিগুলি এম্বেড করা হয়নি বরং পরিবর্তে বাইরের কোনও মডেল ব্যবহার করে যুক্ত করা হয়েছে? (দুঃখিত যদি এটি একটি নূন্যতম প্রশ্ন হয়!)
অ্যাটিলা গাইরিফি

ফ্রান্সিস যেমন ব্যাখ্যা করেছেন, .pluck()পাপ স্থির ব্যবহারটি .mapখুব দ্রুত। আপনি কি ভবিষ্যতের পাঠকদের জন্য আপনার উত্তর আপডেট করতে পারেন?
সিরিল ডুচন-ডরিস

আমি পাচ্ছিundefined method 'pluck' for #<Array:...>
উইলিয়াম জড

7

স্টিভেন Soroka সমাধান সত্যিই দুর্দান্ত! একটি উত্তর মন্তব্য করার মতো খ্যাতি আমার নেই (সে কারণেই আমি একটি নতুন উত্তর যুক্ত করছি: পি) তবে আমি মনে করি যে কোনও সম্পর্কের জন্য মানচিত্র ব্যবহার করা ব্যয়বহুল (বিশেষত যদি আপনার_সম্পর্কিত সম্পর্কের ক্ষেত্রে হ্যান্ডস | হাজার হাজার রেকর্ড থাকে) কারণ এটি পায় ডাটাবেস থেকে ডেটা, প্রতিটি রেকর্ড তৈরি করে, মূল অ্যারে উত্পন্ন করে এবং তারপরে প্রদত্ত ব্লক থেকে মানগুলি সহ একটি নতুন তৈরি করতে মূল অ্যারের উপরে পুনরাবৃত্তি হয়।

প্লাক ব্যবহার করা দ্রুত এবং সম্ভবত দ্রুততম বিকল্প।

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 { 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 টি অ্যাপয়েন্টমেন্ট ব্যবহার করছি। সূচিপত্র যুক্ত করতে ভুলবেন না: রোগী_আইডি এবং: চিকিত্সক_আইডমেন্ট অ্যাপয়েন্টমেন্ট নথিতে!

আমি আশা করি এটি সাহায্য করে, পড়ার জন্য ধন্যবাদ!


আমি পাচ্ছিundefined method 'pluck' for #<Array:...>
উইলিয়াম জড

0

আমি এই প্রশ্নের উত্তরটি স্ব-রেফারেন্সিং অ্যাসোসিয়েশন দৃষ্টিকোণ থেকে দিতে চাই, কেবলমাত্র হ্যাস_মানি নয়: দৃষ্টিকোণের মাধ্যমে।

ধরা যাক আমাদের পরিচিতিগুলির সাথে একটি সিআরএম রয়েছে। পরিচিতিগুলির অন্য পরিচিতির সাথে সম্পর্ক থাকবে তবে দুটি ভিন্ন মডেলের মধ্যে সম্পর্ক তৈরি করার পরিবর্তে আমরা একই মডেলের দুটি উদাহরণের মধ্যে একটি সম্পর্ক তৈরি করব। একটি পরিচিতিতে অনেক বন্ধু থাকতে পারে এবং অন্য অনেক পরিচিতির সাথে বন্ধুত্ব হতে পারে যাতে আমাদের অনেক বেশি সংখ্যক সম্পর্ক তৈরি করতে হয়।

আমরা যদি কোনও আরডিবিএমএস এবং অ্যাক্টিভেকর্ড ব্যবহার করি তবে আমরা has_many: মাধ্যমে ব্যবহার করব। এভাবে আমাদের বন্ধুত্বের মতো একটি জয়েন মডেল তৈরি করা দরকার। এই মডেলটির দুটি ক্ষেত্র থাকবে, একটি পরিচিতি_আইড যা বর্তমান পরিচিতিকে প্রতিনিধিত্ব করে যিনি বন্ধু যুক্ত করছেন এবং বন্ধু_আইড যা ব্যবহারকারীর সাথে বন্ধুত্বের প্রতিনিধিত্ব করছে represents

তবে আমরা মঙ্গোডিবি এবং মঙ্গয়েড ব্যবহার করছি। উপরে উল্লিখিত হিসাবে, মঙ্গয়েডের হাতে_মানি নেই: মাধ্যমে বা সমতুল্য বৈশিষ্ট্য। এটি মঙ্গোডিবি-তে এতটা কার্যকর হবে না কারণ এটি যোগদানের প্রশ্নগুলিকে সমর্থন করে না। অতএব, মোংগোডিবি-এর মতো অ আরডিবিএমএস ডাটাবেসে অনেকগুলি সম্পর্ককে মডেল করতে আপনি উভয় পক্ষের 'বিদেশী' কীগুলির একটি অ্যারে যুক্ত ক্ষেত্র ব্যবহার করেন।

class Contact
  include Mongoid::Document
  has_and_belongs_to_many :practices
end

class Practice
  include Mongoid::Document
  has_and_belongs_to_many :contacts
end

নথি হিসাবে বলা হয়েছে:

অনেকগুলি সম্পর্কের ক্ষেত্রে যেখানে বেস ডকুমেন্ট থেকে বিপরীতমুখী দলিলগুলি পৃথক সংগ্রহে সংরক্ষণ করা হয় মঙ্গয়েডের has_and_belongs_to_many ম্যাক্রো ব্যবহার করে সংজ্ঞায়িত করা হয়। এটি অ্যাক্টিভ রেকর্ডের সাথে একই রকম আচরণ প্রদর্শন করে এই ব্যতিক্রমটি সহ যে কোনও যোগদানের সংগ্রহের প্রয়োজন নেই, বিদেশী কী আইডিগুলি সম্পর্কের উভয় দিকে অ্যারে হিসাবে সংরক্ষণ করা হয়।

এই প্রকৃতির কোনও সম্পর্ককে সংজ্ঞায়িত করার সময়, প্রতিটি নথি তার নিজ নিজ সংগ্রহে সংরক্ষণ করা হয় এবং প্রতিটি নথিতে অ্যারের আকারে অন্যটির সাথে একটি "বিদেশী কী" উল্লেখ রয়েছে।

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

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

মঙ্গোডিবিতে এখন একটি স্ব-রেফারেন্সিং অ্যাসোসিয়েশনের জন্য আপনার কাছে কয়েকটি বিকল্প রয়েছে।

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

সম্পর্কিত পরিচিতি এবং পরিচিতিগুলির অনেকের মধ্যে থাকা এবং অনেকগুলি অনুশীলনের সাথে সম্পর্কিত এর মধ্যে পার্থক্য কী? বিশাল পার্থক্য! একটি দুটি সত্তার মধ্যে একটি সম্পর্ক। অন্যটি একটি স্ব-রেফারেন্স।


উদাহরণ নথি একই বলে মনে হচ্ছে?
সাইবারমিউ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.