$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 байта (полезен товар на низ и кратко име на поле) са незначителни.