El $regex
y MongoRegex (es decir, un tipo de expresión regular BSON que se usa en una coincidencia de igualdad) solo admite coincidencias con cadenas, por lo que no puede usarlas directamente con un ObjectId.
Con respecto a su último ejemplo de código, intentó usar $where
en un constructor MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
El constructor de toma una sola cadena (por ejemplo, /foo/i
), de donde deriva el patrón y las banderas. $where
está destinado a ser utilizado como un operador de consulta de nivel superior (no asociado con ningún nombre de campo). No sigo lo que estás haciendo con $dataProps[$i]
, pero supongamos que estuvieras construyendo un solo $where
consulta para que coincida con la representación de cadena de un ObjectId. El documento de consulta tendría el siguiente aspecto:
{ $where: 'this._id.str.match(/00005/)' }
Tenga en cuenta que estoy accediendo a str
propiedad aquí en lugar de invocar toString()
. Eso es porque toString()
en realidad devuelve la representación de shell del ObjectId. Puede ver esto comprobando su origen en el shell:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Además, si simplemente está comprobando si existe una subcadena en el _id
de representación hexadecimal, es posible que desee utilizar indexOf()
(con un != -1
comparación) en lugar de match()
con una expresión regular.
Dicho esto, usando $where
generalmente es una mala idea si no lo combina con criterios de consulta adicionales que pueden utiliza un índice. Esto se debe a que $where
invoca al intérprete de JavaScript para cada documento considerado en el conjunto de resultados. Si lo combina con otros criterios más selectivos, MongoDB puede usar un índice y restringir los documentos que necesita evaluar con $where
; sin embargo, te encontrarás en un mal momento si estás usando $where
y escanear muchos documentos o escanear una tabla en el peor de los casos.
Probablemente sea mejor crear un segundo campo en cada documento que contenga la representación de cadena hexadecimal del _id
. Luego, puede indexar ese campo y consultarlo usando una expresión regular. Las consultas de expresiones regulares no ancladas seguirán siendo un poco ineficientes (ver:uso del índice regex
en los documentos), pero esto debería ser mucho más rápido que usar $where
.
Esta solución (duplicar el _id
cadena) incurrirá en algo de almacenamiento adicional por documento, pero puede decidir que los 24-30 bytes adicionales (carga de cadena y un nombre de campo corto) son insignificantes.