Il $regex
e MongoRegex (ovvero un tipo regex BSON utilizzato in una corrispondenza di uguaglianza) supportano solo la corrispondenza con le stringhe, quindi non puoi usarle direttamente con un ObjectId.
Per quanto riguarda il tuo ultimo esempio di codice, hai tentato di utilizzare $where
in un costruttore MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
il costruttore di 's accetta una singola stringa (ad es. /foo/i
), da cui deriva il motivo e le bandiere. $where
deve essere utilizzato come operatore di query di primo livello (non associato a nessun nome di campo). Non seguo quello che stai facendo con $dataProps[$i]
, ma supponiamo che tu stia costruendo un singolo $where
query in modo che corrisponda alla rappresentazione di stringa di un ObjectId. Il documento di query sarebbe simile al seguente:
{ $where: 'this._id.str.match(/00005/)' }
Nota che sto accedendo a str
proprietà qui invece di invocare toString()
. Questo perché toString()
restituisce effettivamente la rappresentazione della shell di ObjectId. Puoi vederlo controllando la sua fonte nella shell:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Inoltre, se stai semplicemente controllando se esiste una sottostringa in _id
rappresentazione esadecimale di, potresti voler usare indexOf()
(con un != -1
confronto) invece di match()
con una regex.
Detto questo, usando $where
è generalmente una cattiva idea se non lo stai combinando con criteri di query aggiuntivi che possono usa un indice. Questo perché $where
richiama l'interprete JavaScript per ogni documento considerato nel set di risultati. Se lo combini con altri criteri più selettivi, MongoDB può utilizzare un indice e restringere i documenti che deve valutare con $where
; tuttavia, stai passando un brutto momento se stai usando $where
e la scansione di molti documenti o la scansione di una tabella nel peggiore dei casi.
Probabilmente faresti meglio a creare un secondo campo in ogni documento che contenga la rappresentazione della stringa esadecimale del _id
. Quindi, puoi indicizzare quel campo e interrogarlo usando un'espressione regolare. Le query regex non ancorate saranno ancora un po' inefficienti (vedi:uso dell'indice regex
nei documenti), ma dovrebbe essere comunque molto più veloce rispetto all'utilizzo di $where
.
Questa soluzione (duplicando il _id
string) comporterà una certa quantità di spazio di archiviazione aggiuntivo per documento, ma potresti decidere che i 24-30 byte aggiuntivi (carico utile della stringa e un nome di campo breve) siano trascurabili.