Der $regex
und MongoRegex (d. h. ein BSON-Regex-Typ, der in einem Gleichheitsvergleich verwendet wird) unterstützen nur den Vergleich mit Zeichenfolgen, sodass Sie sie nicht direkt mit einer ObjectId verwenden können.
In Bezug auf Ihr letztes Codebeispiel haben Sie versucht, $where
zu verwenden in einem MongoRegex-Konstruktor:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
Der Konstruktor von nimmt einen einzelnen String (z. B. /foo/i
), von dem es das Muster und die Flaggen ableitet. $where
soll als Abfrageoperator der obersten Ebene verwendet werden (nicht mit einem Feldnamen verknüpft). Ich verstehe nicht, was Sie mit $dataProps[$i]
machen , aber nehmen wir an, Sie würden ein einzelnes $where
erstellen Abfrage, um die Zeichenfolgendarstellung einer ObjectId abzugleichen. Das Abfragedokument würde wie folgt aussehen:
{ $where: 'this._id.str.match(/00005/)' }
Beachten Sie, dass ich auf str
zugreife Eigenschaft hier, anstatt toString()
aufzurufen . Das liegt daran, dass toString()
gibt tatsächlich die Shell-Darstellung der ObjectId zurück. Sie können dies sehen, indem Sie die Quelle in der Shell überprüfen:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Auch, wenn Sie einfach prüfen, ob ein Teilstring in der _id
vorhanden ist 's Hex-Darstellung können Sie indexOf()
(mit einem != -1
Vergleich) statt match()
mit einem regulären Ausdruck.
Das heißt, mit $where
ist im Allgemeinen eine schlechte Idee, wenn Sie sie nicht mit zusätzlichen Abfragekriterien kombinieren, die möglich sind Verwenden Sie einen Index. Das liegt daran, dass $where
ruft den JavaScript-Interpreter für jedes in der Ergebnismenge berücksichtigte Dokument auf. Wenn Sie es mit anderen, selektiveren Kriterien kombinieren, kann MongoDB einen Index verwenden und die Dokumente eingrenzen, die es mit $where
auswerten muss; Allerdings steht Ihnen eine schlechte Zeit bevor, wenn Sie $where
verwenden und Scannen vieler Dokumente oder im schlimmsten Fall ein Tabellenscan.
Es ist wahrscheinlich besser, in jedem Dokument ein zweites Feld zu erstellen, das die Hex-String-Darstellung der _id
enthält . Dann können Sie dieses Feld indizieren und mit einer Regex danach fragen. Die nicht verankerten Regex-Abfragen werden immer noch etwas ineffizient sein (siehe:regex index use
in der Dokumentation), aber das sollte immer noch viel schneller sein als die Verwendung von $where
.
Diese Lösung (Duplizieren der _id
string) etwas zusätzlichen Speicherplatz pro Dokument, aber Sie können entscheiden, dass die zusätzlichen 24-30 Bytes (String-Nutzdaten und ein kurzer Feldname) vernachlässigbar sind.