$regex
och MongoRegex (dvs en BSON-regex-typ som används i en likhetsmatchning) stöder bara matchning mot strängar, så du kan inte använda dem direkt med ett ObjectId.
När det gäller ditt senaste kodexempel, försökte du använda $where
i en MongoRegex-konstruktor:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
s konstruktor tar en enda sträng (t.ex. /foo/i
), varifrån den härleder mönstret och flaggorna. $where
är avsedd att användas som en frågeoperator på toppnivå (ej associerad med något fältnamn). Jag följer inte vad du gör med $dataProps[$i]
, men låt oss anta att du konstruerade en enda $where
fråga för att matcha en ObjectIds strängrepresentation. Frågedokumentet skulle se ut så här:
{ $where: 'this._id.str.match(/00005/)' }
Observera att jag använder str
egenskap här istället för att anropa toString()
. Det beror på att toString()
returnerar faktiskt skalrepresentationen av ObjectId. Du kan se detta genom att kontrollera dess källa i skalet:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Dessutom, om du helt enkelt kontrollerar om en delsträng finns i _id
s hex-representation, kanske du vill använda indexOf()
(med en != -1
jämförelse) istället för match()
med ett regex.
Som sagt, med $where
är i allmänhet en dålig idé om du inte kombinerar det med ytterligare frågekriterier som kan använd ett index. Detta beror på att $where
anropar JavaScript-tolken för varje dokument som beaktas i resultatuppsättningen. Om du kombinerar det med andra, mer selektiva kriterier, kan MongoDB använda ett index och begränsa de dokument som den behöver utvärdera med $where
; du har dock en dålig tid om du använder $where
och skanna många dokument eller en bordsskanning i värsta fall.
Det är förmodligen bättre att skapa ett andra fält i varje dokument som innehåller hex-strängrepresentationen för _id
. Sedan kan du indexera det fältet och fråga efter det med hjälp av ett regex. De icke-förankrade regex-frågorna kommer fortfarande att vara lite ineffektiva (se:regex index use
i dokumenten), men detta borde fortfarande vara mycket snabbare än att använda $where
.
Denna lösning (duplicerar _id
sträng) kommer att medföra lite extra lagring per dokument, men du kan bestämma att de ytterligare 24-30 byte (sträng nyttolast och ett kort fältnamn) är försumbar.