De $regex
en MongoRegex (d.w.z. een BSON-regextype dat wordt gebruikt in een gelijkheidsovereenkomst) ondersteunen alleen overeenkomsten met tekenreeksen, dus u kunt ze niet rechtstreeks gebruiken met een ObjectId.
Wat betreft uw laatste codevoorbeeld, u heeft geprobeerd $where
. te gebruiken in een MongoRegex-constructor:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
's constructor neemt een enkele string (bijv. /foo/i
), waaruit het het patroon en de vlaggen afleidt. $where
is bedoeld om te worden gebruikt als een query-operator op het hoogste niveau (niet gekoppeld aan een veldnaam). Ik volg niet wat je doet met $dataProps[$i]
, maar laten we aannemen dat je een enkele $where
. aan het maken bent query om overeen te komen met de tekenreeksrepresentatie van een ObjectId. Het zoekdocument ziet er als volgt uit:
{ $where: 'this._id.str.match(/00005/)' }
Merk op dat ik toegang heb tot de str
eigenschap hier in plaats van toString()
aan te roepen . Dat komt omdat toString()
geeft feitelijk de shell-representatie van de ObjectId terug. Je kunt dit zien door de bron in de shell te controleren:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Ook als u gewoon controleert of er een subtekenreeks bestaat in de _id
's hex-representatie, wilt u misschien indexOf()
(met een != -1
vergelijking) in plaats van match()
met een regex.
Dat gezegd hebbende, met behulp van $where
is over het algemeen een slecht idee als je het niet combineert met aanvullende zoekcriteria die kunnen gebruik een index. Dit komt omdat $where
roept de JavaScript-interpreter op voor elk document dat in de resultatenset wordt beschouwd. Als je het combineert met andere, meer selectieve criteria, kan MongoDB een index gebruiken en de documenten die het moet evalueren, verfijnen met $where
; je gaat echter een slechte tijd tegemoet als je $where
. gebruikt en in het ergste geval veel documenten of een tabelscan scannen.
Het is waarschijnlijk beter om in elk document een tweede veld te maken dat de hexadecimale tekenreeksrepresentatie van de _id
bevat . Vervolgens kunt u dat veld indexeren en ernaar opvragen met behulp van een regex. De niet-verankerde regex-query's zullen nog steeds een beetje inefficiënt zijn (zie:regex index gebruik
in de documenten), maar dit zou nog steeds veel sneller moeten zijn dan het gebruik van $where
.
Deze oplossing (dupliceren van de _id
string) zal wat extra opslagruimte per document met zich meebrengen, maar u kunt besluiten dat de extra 24-30 bytes (string-payload en een korte veldnaam) te verwaarlozen zijn.