mongo shellから検索クエリはわかるけど、Rubyドライバでの書き方がわからんときの解決法

BSONなので、BSON経由で変換すればいい話ですね。
例えば、下のようなMongoDBドキュメントがあったとします。

{
        "_id" : ObjectId("51b6f5414eba1e94ba5bf762"),
        "info" : {
                "category" : "file",
                "started" : "2013-06-11 18:59:52",
                "ended" : "2013-06-11 19:00:48",
                "version" : "0.5",
                "duration" : "55 seconds",
                "id" : 3921
        }
}

info.startedは開始日時を表しており、これを使ってフィルタをかけたいとします。
mongo shell で書くとこんな感じです。

{ "info.started": {$gte: "2013-06-10",$lt: "2013-06-11"}}

当たり前ですが
Rubyドライバで以下のようにすると、データ量にもよりますが死ぬほど時間がかかります。

coll.find().each do |doc|
  # ここでフィルタ
end

find()の第1引数でフィルタをかけるべきですが、複雑なMongoDBドキュメントになればなるほど、
どういうふうに書けばいいかわからなくなります。
ドキュメントには基本的な構文しか載っていません。

MongoDBの検索クエリはBSON形式なので、mongo shellで書いた検索クエリをBSON形式に変換し、
Rubyドライバでデシリアライズすればよさそうです。

mongo shellはJavaScriptなので、JS用のドライバで検索クエリをシリアライズします。
MongoDBにはjs-bsonというライブラリがついていて、ブラウザからも使えます。

js-bson
https://github.com/mongodb/js-bson


browser_build/bson.jsを適当な場所に配置して、同じフォルダに以下のファイルを置きます。
js-bsonのREADMEに書いてあったものを持ってきて、コンソール出力するように修正しただけです。

<head>
  <script src="./bson.js">
  </script>
</head>
<body onload="start();">
<script>
  function start() {
    var BSON = bson().BSON;
    var Long = bson().Long;

    var doc = {//ここに検索クエリを書く}
    // 例えばこんな感じ
    // var doc = {"info.started": {$gte: "2013-06-10",$lt: "2013-06-11"}}

    var data = BSON.serialize(doc, false, true, false);
    console.log(data)
        
  }
</script>
</body>

これでBSON形式の検索クエリがブラウザのコンソールに出力されます。
ChromeであればF12キーを押して、consoleタブに移動するだけです。

BSON形式のバイナリは10進数の配列で表示されます。
16進数でRubyでデシリアライズできる形式に変更したいので、Rubyで成型します。

require 'bson'
# ブラウザに表示された配列をコピーしてirbの変数に代入します。
bson = [65, 0, 0, 0, 3, 105, 110, 102, 111, 46, 115, 116, 97, 114, 116, 101, 100, 0, 46, 0, 0, 0, 2, 36, 103, 116, 101, 0, 11, 0, 0, 0, 50, 48, 49, 51, 45, 48, 54, 45, 49, 48, 0, 2, 36, 108, 116, 0, 11, 0, 0, 0, 50, 48, 49, 51, 45, 48, 54, 45, 49, 49, 0, 0, 0]
# 16進数に変換します
hex = bson.map {|x| "%02X" % x}
# 結合します
msg << hex.join
# Rubyのバイナリ形式に変換します
bin = msg.pack("H*")
# BSON形式をデシリアライズします
BSON.deserialize(bin.unpack("C*"))
# => {"info.started"=>{"$gte"=>"2013-06-10", "$lt"=>"2013-06-11"}}

あとはこの検索クエリをRubyドライバから使うだけです。