$regex
i MongoRegex (tj. typ wyrażenia regularnego BSON używany w dopasowaniu równości) obsługują tylko dopasowanie względem ciągów, więc nie można ich używać bezpośrednio z ObjectId.
Jeśli chodzi o twój ostatni przykład kodu, próbowałeś użyć $where
w konstruktorze MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
Konstruktor pobiera pojedynczy ciąg (np. /foo/i
), z którego wywodzi się wzór i flagi. $where
jest przeznaczony do użycia jako operator zapytań najwyższego poziomu (niezwiązany z żadną nazwą pola). Nie śledzę tego, co robisz z $dataProps[$i]
, ale załóżmy, że tworzysz pojedynczy $where
zapytanie pasujące do reprezentacji ciągu ObjectId. Dokument zapytania wyglądałby następująco:
{ $where: 'this._id.str.match(/00005/)' }
Zauważ, że mam dostęp do str
tutaj właściwość zamiast wywoływania toString()
. To dlatego, że toString()
faktycznie zwraca reprezentację powłoki ObjectId. Możesz to zobaczyć, sprawdzając jego źródło w powłoce:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Ponadto, jeśli po prostu sprawdzasz, czy podciąg istnieje w _id
reprezentacji szesnastkowej, możesz użyć indexOf()
(z != -1
porównanie) zamiast match()
z wyrażeniem regularnym.
To powiedziawszy, używając $where
jest ogólnie złym pomysłem, jeśli nie łączysz go z dodatkowymi kryteriami zapytania, które mogą użyj indeksu. Dzieje się tak, ponieważ $where
wywołuje interpreter JavaScript dla każdego dokumentu uwzględnionego w zestawie wyników. Jeśli połączysz to z innymi, bardziej selektywnymi kryteriami, MongoDB może użyć indeksu i zawęzić dokumenty, które musi ocenić za pomocą $where
; jednak jesteś w złym czasie, jeśli używasz $where
i skanowanie wielu dokumentów lub skan stołu w najgorszym przypadku.
Prawdopodobnie lepiej jest utworzyć drugie pole w każdym dokumencie, które zawiera ciąg szesnastkowy reprezentujący _id
. Następnie możesz zindeksować to pole i wykonać zapytanie za pomocą wyrażenia regularnego. Niezakotwiczone zapytania regex nadal będą nieco nieefektywne (patrz:użyj indeksu wyrażeń regularnych
w dokumentacji), ale nadal powinno to być znacznie szybsze niż użycie $where
.
To rozwiązanie (powielanie _id
string) spowoduje zwiększenie ilości miejsca na dokument, ale możesz zdecydować, że dodatkowe 24-30 bajtów (ładowność ciągu i krótka nazwa pola) jest znikome.