$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.