mongo からオブジェクトの単一のコレクションを返す必要がある状況がありますが、結果を取得するには 2 つのクエリを使用する必要があります。これらの結果はページ付けされるため、これらの結果の順序は重要です。
最初のクエリは次のとおりです: (カテゴリと価格帯に基づくリスト)
my_listings = MoListing.where(criteria_a)
2 番目のクエリは、最初のクエリの結果をフィルターとして使用する必要があります。次のようなものです:
everything_else = MoListing.where(criteria_b)
次に、結果を結合します。
my_listings << everything_else
最後に、ページ分割された結果を返します。
my_listings.page(1).per(25)
私の問題の一部は、必要になるまでmongoクエリが実行されないことです。特定の時点でクエリの実行をトリガーする方法はありますか? または、この結果セットを構築する際に取るべき別のアプローチはありますか?
詳細情報を更新
私が見ている動作は、返されるのは の結果だけlistings
です。everything_else
また、予想されるレコードが含まれていることも確認しました (予想どおり、my_listings に 48 レコード、everything_else に 52 レコード)。
.all
コメントに記載されているようにクエリに適用しても、影響はありません。のputs listings.inspect
結果
10:57:00 web.1 | #<Mongoid::Criteria
10:57:00 web.1 | selector: {"price"=>{"$gte"=>25, "$lte"=>75}},
10:57:00 web.1 | options: {},
10:57:00 web.1 | class: MoListing,
10:57:00 web.1 | embedded: false>
ただし、listings.count
結果は48
. これらの結果をマージする愚かで簡単な方法が欠けているだけですか? そして、結果を 1 つのコレクションにまとめたら、これが後続のページ付け機能にどのような影響を与えるでしょうか。ページネーションに使用kaminari
しています。
更新 2
以下の回答と私自身の試行錯誤により、 to_a が解決策であることがわかりましたが、理想的なものではありません。これは機能します:
#merge the results together as an Array
results = (listings.to_a | everything_else.to_a)
これにより、mongo 基準ではなく標準の配列を使用するようになったため、Kaminari を介したページ付けを変更する必要があります。新しいページネーション方法は次のとおりです。
Kaminari.paginate_array(results).page(page).per(per_page)
100 レコードの小さなデータセットで作業すると、これは問題なくダンディです - 54 ミリ秒
"debug":{"success":true,"pre_render_duration":54.808775999999995,"overall_duration":86.36554100000001,"count":25},"pagination":{"total_pages":4,"current_page":1}}
ただし、より大きなデータセットを使用すると、 .to_a メソッドを使用してこれらを組み合わせると、時間が大幅に遅くなります。例は厳密には同じではありませんが、この大きな違いは、to_a がすべてを返すという問題を示しており、Kaminari はより多くの実際のデータを操作する必要があります。
to_a を使用しない結果、条件が適用されたすべてのレコードを返すだけ - 15ms
"debug":{"success":true,"pre_render_duration":15.107164,"overall_duration":18.267599,"count":25},"pagination":{"total_pages":81,"current_page":1}}
to_a での結果、2 つの結果セットのマージ - 415ms
"debug":{"success":true,"pre_render_duration":415.258199,"overall_duration":450.66537800000003,"count":25},"pagination":{"total_pages":81,"current_page":1}}
要約すると、これは有効なオプションではありません。各データセットを個別に返すには、大規模なデータセットでも 15 ミリ秒未満かかるため、達成する必要があるのは、単一のクエリが Mongo に対して実行されるように基準をマージする方法であると思います。なれ。
SQLでは、おおよそ次のようなことをします
select
*
from
listings
where
field = "blah"
union all
select
*
from
listings
where
field <> "blah"
Mongoでこれを行うことは可能ですか?