Make the MongoDB docs better! We value your opinion. Share your feedback for a chance to win $100.
Click here >
Docs Menu
Docs Home
/ /

クエリ結果の変更

このガイドでは、Mongoid がクエリから結果を返す方法をカスタマイズする方法を学習できます。 MongoDB、次のアクションを実行して結果の表示方法を変更できます。

  • 指定されたフィールドを返す

  • 結果を並べ替える

  • 結果のページ分割

  • より負荷の高い関連付け

  • Return Raw Data

このガイドの例では、バンドまたはステージを表す Band モデルを使用します。 Band モデルの定義は、異なるクエリ機能を示すために、各セクションで異なる場合があります。 一部のセクションでは、特定のバンドを管理するユーザーを表す Manager モデルや、特定のバンドによるライブ パフォーマンスを表す Tour モデルも使用します。

MongoDBでは、プロジェクションとは、結果に含めるフィールドまたは除外するフィールドを指定するプロセスです。Mongoid は、フィールドをプロジェクトために次の演算子を提供します。

  • only: 含めるフィールドを指定します

  • without: 除外するフィールドを指定します

only メソッドは、データベースから指定されたフィールドのみを検索します。

次のコードでは、membersフィールドの値が 4 であるドキュメントから nameフィールドのみが返されます。

Band.where(members: 4).only(:name)

注意

_id フィールド

MongoDBでは、明示的に含めない場合でも _idフィールドは結果に含まれます。

ロードされていない属性を参照しようとすると、Mongoid は Mongoid::Errors::AttributeNotLoaded エラーを発生させます。

また、 only メソッドを使用して、埋め込みドキュメントのフィールドを含めることもできます。

Band モデルには複数の Tour オブジェクトが埋め込まれている ことを考えてみましょう。 次のコードに示すように、year などの Tour モデルからフィールドをプロジェクトできます。

bands = Band.only(:name, 'tours.year')

次に、返されたドキュメントから埋め込みフィールドにアクセスできます。

# Returns the first Tour object from
# the first Band in the results
bands.first.tours.first

参照された関連付けのフィールドを only メソッドに渡すことはできますが、埋め込みオブジェクトをロードするときにプロジェクションは無視されます。 Mongoid は、参照先の関連付けのすべてのフィールドをロードします。 例、前述のコードに示すように、埋め込み Tourオブジェクトにアクセスすると、Mongoid は yearフィールドだけでなく、完全なオブジェクトを返します。

注意

MongoDB 4.4 以降を実行中配置に接続している場合、同じクエリで関連付けとそのプロジェクションのフィールドを指定することはできません。

ドキュメントに has_one または has_and_belongs_to_many の関連付けが含まれており、only メソッドを呼び出すときに Mongoid がそれらの関連付けをロードする場合は、属性のリストに外部キーを持つフィールドを含める必要があります。

次の例では、Band モデルと Manager モデルに has_and_belongs_to_many の関連付けがあります。

class Band
include Mongoid::Document
field :name, type: String
has_and_belongs_to_many :managers
end
class Manager
include Mongoid::Document
has_and_belongs_to_many :bands
end

次のコードは、manager_idsフィールドを含める場合に Mongoid が関連する Manager オブジェクトをロードする方法を示しています。

# Returns null
Band.where(name: 'Astral Projection').only(:name).first.managers
# Returns the first Manager object
Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers

without メソッドを使用して、結果からフィールドを明示的に除外できます。

次のコードでは、返される Band オブジェクトから yearフィールドが除外されます。

Band.where(members: 4).without(:year)

重要

_id フィールド

Mongoid ではさまざまな操作に_id フィールドが必要になるため、結果から _idフィールドまたはid エイリアスを除外することはできません。without メソッドに _id または id を渡すと、Mongoid はそれを無視します。

Mongoid がドキュメントを返す順序を指定するには、order メソッドと order_by メソッドを使用します。

これらのメソッドは、ドキュメントをどのフィールドで並べ替えるか、および各フィールドに対して昇順または降順のどちらを使用するかを示すハッシュを受け入れます。

整数、記号、または string を使用してソート方向を指定できます。 整合性を高めるために、アプリケーション全体で同じソート構文を使用することをお勧めします。 次のリストは、それぞれの構文と、name フィールドと year フィールドで並べ替える方法を示しています。

  • 整数 1(昇順)と -1(降順)

    • 例: Band.order(name: 1, year: -1)

  • 記号 :asc:desc

    • 例: Band.order(name: :asc, year: :desc)

  • String "asc""desc"

    • 例: Band.order_by(name: "asc", year: "desc")

order メソッドは次の並べ替え指定も受け入れています。

  • 2 つの要素からなる配列の配列:

    • 文字列

      • 例: Band.order([['name', 'asc'], ['year', 'desc']])

    • 記号

      • 例: Band.order([[:name, :asc], [:year, :desc]])

  • asc シンボルの メソッドと desc メソッド

    • 例: Band.order(:name.asc, :year.desc)

  • SQL構文

    • 例: Band.order('name asc', 'year desc')

Tip

order または order_by を使用する代わりに、asc メソッドと desc メソッドを使用して並べ替え順序を指定することもできます。

Band.asc('name').desc('year')

ソート指定を連鎖させる場合、最初の呼び出しは最初のソート順序を定義し、最後の呼び出しは前のソートが適用された後の最後のソート順序を定義します。

注意

スコープ内でのソート

並べ替え指定を含むモデルで のデフォルトスコープを定義すると、デフォルトのスコープが最初に評価されるため、スコープの並べ替えがクエリで指定された並べ替えよりも優先されます。

Mongoid は、Criteria オブジェクトで使用できる limitskipbatch_size のページ区切りメソッドを提供します。 次のセクションでは、これらの演算子の使用方法について説明します。

Mongoid が返す結果の数を制限するには、limit メソッドを使用します。

次のコードは、最大 5 ドキュメントを検索します。

Band.limit(5)

注意

あるいは、take メソッドを使用して、データベースから指定した数のドキュメントを検索することもできます。

Band.take(5)

skip メソッドまたはそのエイリアス offset を使用すると、指定した数の結果をスキップできます。

skip への limit 呼び出しを連鎖させると、次の例に示すように、ドキュメントがスキップされた後に制限が適用されます。

Band.skip(2).limit(5)
# Skips the first two results and returns
# the following five results

Tip

ページネーションを行う際には、一貫した結果を得るために、ソートされた結果にskip を使用します。

次のコードは、結果を返すときに最初の 3 ドキュメントをスキップします。

Band.skip(3)
# Equivalent
Band.offset(3)

大規模なクエリを実行する場合、およびCriteria#each などの列挙メソッドを使用してクエリ結果を反復処理する場合、Mongoid は自動的にMongoDB getMore コマンド を使用して結果をバッチで読み込みます。デフォルトのバッチするサイズは 1000 ですが、batch_size メソッドを使用して別の値を設定できます。

次のコードを使用することで、バッチするサイズが 500 に設定されます。

Band.batch_size(500)

関連付けを含むドキュメントをクエリする場合、早期ロードにより、関連するドキュメントを後で遅延してロードするのではなく、関連するドキュメントを基本ドキュメントと同時にロードすることができます。これにより、データベースクエリの数が減り、関連付けが多いワークロードのパフォーマンスが向上します。Mongoid は、関連付けがあるドキュメントをクエリするときに、関連するドキュメントを早期ロードするための 2 つの方法を提供します(includeseager_load)。

includes メソッドは、関連付けごとに個別のクエリを使用して関連付けを読み込みます。次のコードでは、バンドとそれに関連するデータベースとラベルを個別のクエリを使用して読み込みます。

Band.where(name: 'The Beatles').includes({ albums: :songs }, :labels).first

includes メソッドを使用すると、Mongoid は基本クラスに対してクエリを実行してすべての基本ドキュメントを取得し、その後に早期ロードする関連付けごとに個別のクエリを実行します。

前の例では、次のクエリが実行されます。

  • Band ドキュメントを検索するための 1 回のクエリ

  • 関連する Album ドキュメントを読み込む 1 つのクエリ

  • 関連する Label ドキュメントを読み込む 1 つのクエリ

  • 関連する Song ドキュメントを読み込む 1 つのクエリ

eager_load メソッドは、 MongoDB集計パイプラインを$lookup 演算子とともに使用して、1 回のクエリですべての関連付けを読み込みます。次のコードでは、単一の集計パイプラインクエリを使用して、バンドとそれに関連するデータベースとラベルを読み込みます。関連付けごとに $lookup ステージが含まれます。

Band.where(name: 'The Beatles').eager_load({ albums: :songs }, :labels).first

includes メソッドと eager_load メソッドはどちらも早期読み込みを実行しますが、その方法は異なります。includes メソッドは基本ドキュメントに対して 1 つのクエリを実行し、その後 関連付けごとに個別のクエリを実行します。eager_load メソッドは、関連付けをロードするために、$lookup ステージを持つ単一の集計パイプラインを使用します。

eager_load メソッドは、includes よりもクエリを実行し、使用するメモリが少なくなります。ただし、メソッドの効率は、ドキュメント内の関連付けのタイプによって異なります。

  • eager_load は、has_manyhas_and_belongs_to_many、およびほとんどのデータセットで複数の関連付けの読み込みで高速です

  • includes は、belongs_tohas_one、およびほとんどのデータセットでネストされた関連付けで高速です

ユースケースと関連付けのタイプに最適な方法を選択します。

raw メソッドをクエリに連結することで、モデル インスタンスを作成しなくても、結果を未加工のハッシュとして返すことができます。

次のコードでは、クエリ結果を未加工のハッシュとして検索します。

Band.where(country: 'Argentina').raw

デフォルトでは 、raw メソッドは Mongoid がデータベースからドキュメントを受け取った時点で正確にドキュメントを返します。オプションで、raw メソッドで typed オプションを true に設定することで、結果ハッシュ内のフィールドをモデルフィールド宣言の型にキャストできます。

Band.where(country: 'Argentina').raw(typed: true)

未加工の結果を返すクエリを実行し、後でこれらの結果をモデルに変換したい場合は、結果に対して raw(false) を呼び出せます。

# Retrieves raw results
results = Band.where(members: 4).raw
# ... Perform actions on results
# Returns instantiated model objects from raw results
bands = results.raw(false).to_a

クエリ結果を変更するために Criteria オブジェクトで使用できるメソッドの完全なカタログについては、APIドキュメントの Mongoid::Criteria::Queryable モジュール参照を参照してください。

クエリの構築の詳細については、「ドキュメント クエリの指定」ガイドを参照してください。

Mongoid データ モデリングの詳細については、「 データのモデル化 」ガイドを参照してください。

戻る

CRUD 操作

項目一覧