Alexey Zakharov
Alexey Zakharov

Reputation: 25102

What is the better way to cache fields of referenced document in Mongoid?

What is the better way to cache fields of referenced document in Mongoid?

Currently I use additional fields for that:

class Trip
  include Mongoid::Document

  belongs_to :driver

  field :driver_phone
  field :driver_name

end

class Driver
  include Mongoid::Document

  field :name
  field :phone
end

May be it would be more clear to store cache as nested object so in mongo it would be stored as:

{ driver_cache: { name: "john", phone: 12345 } }

I thought about embedded document with 1-1 relation? Is that right choice?

Upvotes: 0

Views: 353

Answers (5)

Josh Dzielak
Josh Dzielak

Reputation: 1823

Great question. I authored and maintain mongoid_alize, a gem for denormalizing mongoid relations. And so I struggled with this question.

As of 0.3.1 alize now stores data for a denormalized one-to-one in a Hash, very much like your second example above w/ driver_cache. Previous versions, however, stored data in separate fields (your first example).

The change was motivated by many factors, but largely to make the handling of one-to-one's and one-to-many's consistent (alize can denormalize one-to-one, one-to-many, and many-to-many). one-to-many's have always been handled by storing the data in a array of hashes. So storing one-to-one's as just a Hash becomes a much more symmetrical design.

It also solved several other problems. You can find a more detailed explanation here - https://github.com/dzello/mongoid_alize#release-030

Hope that helps!

Upvotes: 1

Alexey Zakharov
Alexey Zakharov

Reputation: 25102

Author of Mongoid (Durran Jordan) suggested folowing option

This gem looks handy for this type of thing:

https://github.com/logandk/mongoid_denormalize

Upvotes: 3

asaaki
asaaki

Reputation: 2000

Alternative hash storage of your cacheable data:

field :driver_cache, type: Hash

(Keep in mind, internally the keys will be converted to strings.)

Upvotes: 0

Tyler Brock
Tyler Brock

Reputation: 30136

Alexey,

I would recommend thinking about how the data will be used. If you always use the driver information in the context of a trip object then embedding is probably the proper choice.

If, however, you will use that information in other contexts perhaps it would be better as it's own collection as you have created it.

Also, consider embedding the trips inside the driver objects. That may or may not make sense given what your app is trying to do but logically it would make sense to have a collection of drivers that each have a set of trips (embedded or not) instead of having trips that embed drivers. I can see that scenario (where a trip is always though of in the context of a driver) to be more common than the above.

-Tyler

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230276

Either way, you're fine.

First approach seems slightly better because it explicitly states what data you're caching. Also, it (probably) requires less work from Mongoid :-)

Upvotes: 0

Related Questions