13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

業務をしていく中で、mongoidを使う機会があったので、この際にmongoidの基礎をまとめてみました!

Mongoidは、RailsのActive Recordに似せて作られているみたいで、Active Recordと比較して話していきます。

Mongoidとは?

MongoDB で公式にサポートされているオブジェクト ドキュメント マッパー(ODM)

ODMとは

保存するデータを JSON ライクな形式で表現し、ドキュメントとして保存しています。このドキュメントとプログラミング言語のオブジェクトとを対応付ける機能のこと

ドキュメント

ドキュメントは Mongoid のコア オブジェクトであり、データベースに永続化するすべてのオブジェクトにはMongoid::Documentを含める必要があります。 MongoDB のドキュメントの表現は、Ruby ハッシュまたは JSON オブジェクトに非常によく似た BSON オブジェクトです。 ドキュメントは データベース内の独自のコレクションに保存することも、 n レベルの深度を持つ他のドキュメントに埋め込むこともできます。

フィールド定義

Active Recordでは、データを永続化する際、一般的にモデルとテーブルスキーマを別々に定義すると思いますが Mongoid では、モデル(フィールド)の定義のみを行います。

公式の引用

フィールドタイプの定義は、クエリを構築し、データベースからフィールドを検索/書き込みするときの Mongoid の動作を決定します

実際の書き方

Mongoidを使うには、includeでmongoidを読み込みます。

class User
  include Mongoid::Document

  field :name, type: String
  field :email, type: String

  validates :name, presence: true
end

id は、(データ型がBSON::ObjectID形式でよければ)勝手についてくるので書かなくても大丈夫です。
ここで一緒にvalidationを行うこともできます。Active Recordと似ていますね

便利メソッド

find_by

条件に従って最初のDocumentを見つけます。 一致するドキュメントが見つからず、Mongoid. Ops Manager が true に設定されている場合には、Mongoid::Errors::DocumentNotFound が発生します。それ以外の場合は、null を返します。

Person.find_by(:username => "superuser")

push

配列に単一の値または複数の値をプッシュします。

配列に単一の値をプッシュします。
document.push(names: "James", aliases: "007")
配列に複数の値をプッシュします。
document.push(names: [ "James", "Bond" ])

updatedestoryなどのActive Recordにある機能もあります

リレーションの定義の仕方

Active Recordでいうところのbelongs_tohas_manyといった機能が、もちろんmongoidにもあります

1 : 1

Mongoid はhas_one、 ActiveRecord ユーザーに馴染みのあるhas_many、 、belongs_toの has_and_belongs_to_many関連付けをサポートしています。

class Band
  include Mongoid::Document
  has_one :studio
end
class Studio
  include Mongoid::Document
  belongs_to :band
end

子のドキュメントに親の参照が含まれる

band = Band.create!(studio: Studio.new)
# => #<Band _id: 600114fa48966848ad5bd392, >

band.studio
# => #<Studio _id: 600114fa48966848ad5bd391, band_id: BSON::ObjectId('600114fa48966848ad5bd392')>

1 : N

関連付けを使用して、has_many親に 0 個以上の子があり、それらが別のコレクションに格納されていることを宣言します。

class Band
  include Mongoid::Document

  has_many :members
end
class Member
  include Mongoid::Document

  belongs_to :band
end

同じようにそれぞれの子のドキュメントに親の参照が含まれる

band = Band.create!(members: [Member.new])
# => #<Band _id: 6001166d4896684910b8d1c5, >

band.members
# => [#<Member _id: 6001166d4896684910b8d1c6, band_id: BSON::ObjectId('6001166d4896684910b8d1c5')>]

埋め込み関連付け 1 : 1

MongoDB のドキュメント モデルのおかげで、Mongoid は埋め込み関連付けも提供しており、異なるタイプのドキュメントを同じコレクション内に階層的に保存できます。埋め込み関連付けは embeds_oneembeds_manyおよびembedded_inマクロを使用して定義されます

定義
・親にembeds_oneマクロを定義。
・子にembedded_inマクロを定義。
・関連付けの両側で定義が必要です。

class Band
  include Mongoid::Document
  embeds_one :label
end

class Label
  include Mongoid::Document
  field :name, type: String
  embedded_in :band
end
band = Band.create!(label: Label.new(name:'Mute'))
# => #<Band _id: 6001166d4896684910b8d1c5, >

embeds_one親のデータベース コレクション内の親内にハッシュとして保存されます。

{
  "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
  "label" : {
    "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
    "name" : "Mute",
  }
}

埋め込み関連付け 1 : N

子が親ドキュメントに埋め込まれている 1 対多の関係は、Mongoidembeds_manyとembedded_inマクロを使用して定義されます。

定義
・親にembeds_manyマクロを定義。
・子にembedded_inマクロを定義。
・関連付けの両側で定義が必要です。

class Band
  include Mongoid::Document
  embeds_many :albums
end

class Album
  include Mongoid::Document
  field :name, type: String
  embedded_in :band
end

embeds_many親のデータベース コレクション内の親内にハッシュの配列として保存されます。

{
  "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
  "albums" : [
    {
      "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
      "name" : "Violator",
    }
  ]
}

まとめ

今回、Active RecordからMongoidを使ってみた感想としては、フィールド定義めっちゃ便利で楽だなと思いました。ですが、トランザクションの利用に制限があったり、外部キー制約等(合成外部キーというのがあるらしいが、、)がないこともあり、
整合性が求められるアプリケーションでは、使うことがないかもしれません😨
やっぱActive Recordですね〜

参考文献

13
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?