$regex
およびMongoRegex(つまり、等式一致で使用されるBSON正規表現タイプ)は文字列との一致のみをサポートするため、ObjectIdで直接使用することはできません。
最後のコード例に関して、$where
を使用しようとしました MongoRegexコンストラクターの場合:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
のコンストラクタは単一の文字列を取ります(例:/foo/i
)、そこからパターンとフラグを導き出します。 $where
トップレベルのクエリ演算子として使用することを目的としています(フィールド名に関連付けられていません)。 $dataProps[$i]
で行っていることをフォローしていません 、しかし、単一の$where
を作成していたとしましょう。 ObjectIdの文字列表現に一致するクエリ。クエリドキュメントは次のようになります。
{ $where: 'this._id.str.match(/00005/)' }
str
にアクセスしていることに注意してください toString()
を呼び出す代わりにここにプロパティ 。これは、toString()
ObjectIdのシェル表現を実際に返します。これは、シェルでソースを確認することで確認できます:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
また、サブストリングが_id
に存在するかどうかを単にチェックしている場合 の16進表現では、 indexOf()
(!= -1
を使用 比較)match()
の代わりに 正規表現付き。
そうは言っても、$where
を使用する 可能な追加のクエリ条件と組み合わせていない場合は、一般的に悪い考えです。 インデックスを使用します。これは、$where
が原因です。 結果セットで考慮される各ドキュメントに対してJavaScriptインタープリターを呼び出します。これを他のより選択的な基準と組み合わせると、MongoDBはインデックスを使用して、$where
で評価する必要のあるドキュメントを絞り込むことができます。;ただし、$where
を使用している場合は、問題が発生します。 最悪の場合、多くのドキュメントまたはテーブルスキャンをスキャンします。
_id
の16進文字列表現を含む2番目のフィールドを各ドキュメントに作成する方がおそらく良いでしょう。 。次に、そのフィールドにインデックスを付け、正規表現を使用してクエリを実行できます。アンカーされていない正規表現クエリは、まだ少し非効率的です(regexインデックスの使用
ドキュメント内)、ただし、これは$where
を使用するよりもはるかに高速である必要があります 。
このソリューション(_id
を複製する string)は、ドキュメントごとに追加のストレージが発生しますが、追加の24〜30バイト(文字列ペイロードと短いフィールド名)は無視できると判断できます。