$regex
и MongoRegex (т.е. тип регулярен израз BSON, използван при съвпадение на равенство) поддържат съвпадение само срещу низове, така че не можете да ги използвате директно с ObjectId.
Относно последния ви пример с код, вие се опитахте да използвате $where в конструктор MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
Конструкторът на 's приема един низ (напр. /foo/i ), откъдето произлиза шаблонът и флаговете. $where
е предназначен да се използва като оператор на заявка от най-високо ниво (не е свързан с име на поле). Не разбирам какво правите с $dataProps[$i] , но да предположим, че конструирате единичен $where заявка за съответствие с представянето на низ на ObjectId. Документът на заявката ще изглежда по следния начин:
{ $where: 'this._id.str.match(/00005/)' }
Имайте предвид, че имам достъп до str свойство тук, вместо да извиквате toString() . Това е така, защото toString() всъщност връща shell представянето на ObjectId. Можете да видите това, като проверите източника му в обвивката:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Освен това, ако просто проверявате дали съществува подниз в _id шестнадесетично представяне на 's, може да искате да използвате indexOf()
(с != -1 сравнение) вместо match() с регулярен израз.
Това каза, използвайки $where обикновено е лоша идея, ако не го комбинирате с допълнителни критерии за заявка, които могат използвайте индекс. Това е така, защото $where извиква JavaScript интерпретатора за всеки документ, разглеждан в резултатния набор. Ако го комбинирате с други, по-селективни критерии, MongoDB може да използва индекс и да стесни документите, които трябва да оцени с $where; обаче ви очаква лошо време, ако използвате $where и сканиране на много документи или сканиране на таблица в най-лошия случай.
Вероятно е по-добре да създадете второ поле във всеки документ, което съдържа шестнадесетичното низово представяне на _id . След това можете да индексирате това поле и да направите заявка за него с помощта на регулярен израз. Незакотвените заявки за регулярен израз все още ще бъдат малко неефективни (вижте:използване на regex index
в документите), но това все пак трябва да е много по-бързо от използването на $where .
Това решение (дублиране на _id низ) ще доведе до допълнително съхранение на документ, но може да решите, че допълнителните 24-30 байта (полезен товар на низ и кратко име на поле) са незначителни.