$regex
a MongoRegex (tj. typ regulárního výrazu BSON používaný při shodě rovnosti) podporují pouze párování s řetězci, takže je nemůžete použít přímo s ObjectId.
Pokud jde o váš poslední příklad kódu, pokusili jste se použít $where v konstruktoru MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
Konstruktor 's bere jeden řetězec (např. /foo/i ), ze kterého odvozuje vzor a příznaky. $where
je určen k použití jako operátor dotazu nejvyšší úrovně (není spojen s žádným názvem pole). Nesleduji, co děláte s $dataProps[$i] , ale předpokládejme, že jste konstruovali jeden $where dotaz, aby odpovídal reprezentaci řetězce ObjectId. Dokument dotazu by vypadal takto:
{ $where: 'this._id.str.match(/00005/)' }
Všimněte si, že přistupuji k str vlastnost zde namísto vyvolání toString() . Je to proto, že toString() ve skutečnosti vrací reprezentaci shellu ObjectId. Můžete to vidět kontrolou jeho zdroje v shellu:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Také, pokud pouze kontrolujete, zda existuje podřetězec v _id hexovou reprezentaci , možná budete chtít použít indexOf()
(s != -1 porovnání) namísto match() s regulárním výrazem.
To znamená, že pomocí $where je obecně špatný nápad, pokud jej nekombinujete s dalšími kritérii dotazu, která může použít index. Je to proto, že $where vyvolá interpret JavaScriptu pro každý dokument uvažovaný v sadě výsledků. Pokud to zkombinujete s jinými, selektivnějšími kritérii, MongoDB může použít index a zúžit dokumenty, které potřebuje vyhodnotit, pomocí $where; pokud však používáte $where, čeká vás špatná doba a skenování mnoha dokumentů nebo skenování stolu v nejhorším případě.
Pravděpodobně bude lepší vytvořit v každém dokumentu druhé pole, které obsahuje hexadecimální reprezentaci _id . Poté můžete toto pole indexovat a dotazovat se na něj pomocí regulárního výrazu. Neukotvené dotazy na regulární výraz budou stále trochu neefektivní (viz:použití indexu regulárních výrazů
v dokumentech), ale stále by to mělo být mnohem rychlejší než použití $where .
Toto řešení (duplikující _id string) bude vyžadovat určité dodatečné úložiště na dokument, ale můžete se rozhodnout, že dalších 24–30 bajtů (užitná zátěž řetězce a krátký název pole) je zanedbatelných.