Для MongoDB 3.6 и новее:
$expr
оператор позволяет использовать агрегирование выражения в языке запросов, таким образом, вы можете использовать использование оператора $strLenCP
для проверки длины строки следующим образом:
db.usercollection.find({
"name": { "$exists": true } },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
Для MongoDB 3.4 и новее:
Вы также можете использовать структуру агрегации с оператором $redact
трубопровода, что позволяет proccess логического условия с оператором в $cond
и использует специальные операции $$KEEP
, чтобы «сохранить» документ, где логическое условие истинно или $$PRUNE
«удалить» документ, в котором условие было ложным.
Эта операция аналогична имеющей $project
трубопровод, который выбирает поля в коллекции и создает новое поле, который содержит результат логического состояния запроса, а затем последующей $match
, за исключением того, что $redact
использования который является более эффективным.
Что касается логического условия, есть String Aggregation Operators, что вы можете использовать $strLenCP
оператора, чтобы проверить длину строки. Если длина равна $gt
указанному значению, то это истинное соответствие, и документ «сохраняется». В противном случае он «обрезается» и отбрасывается.
Считайте, выполнив следующую суммарную работу, которая демонстрирует вышеупомянутую концепцию:
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
При использовании $where
, попробуйте запрос без вмещающих скобках:
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
Лучше запрос должен состоять в том, чтобы проверить существование поля и затем проверить удлинение ч:
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
или:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDB оценивает Непро- операции $where
запроса перед $where
выражений и не- $where
утверждения запроса могут использовать индекс. Более высокая производительность - сохранить длину строки в качестве другого поля, а затем вы можете индексировать или искать на ней; применение $where
будет намного медленнее по сравнению с этим. Рекомендуется использовать выражения JavaScript и оператор $where
в качестве последнего средства, когда вы не можете структурировать данные каким-либо другим способом или когда вы имеете дело с небольшим подмножеством данных .
Другой и более быстрый подход, который позволяет избежать использования оператора $where
является основным оператором $regex
. Рассмотрим следующий шаблон, который осуществляет поиск
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
Примечание - от docs:
Если индекс существует поле, то MongoDB соответствует регулярному выражение против значений в индекс, который может быть быстрее, чем сканирование коллекции . Дальнейшая оптимизация может произойти, если регулярное выражение является «префиксным выражением», что означает, что все потенциальные совпадения начинаются с одной и той же строки. Это позволяет MongoDB построить из этого префикса «диапазон» и соответствовать только этим значениям из индекса , которые попадают в этот диапазон.
Регулярное выражение является «выражением префикса», если она начинается с каретки (^)
или левым якорем (\A)
, за которым следует строка простых символов. Например, регулярное выражение /^abc.*/
будет оптимизировано на , соответствующее только значениям индекса, начинающимся с abc
.
Кроме того, в то время как /^a/, /^a.*/,
и /^a.*$/
соответствуют эквиваленту строк , они имеют разные характеристики. Все эти выражения используют индекс, если существует соответствующий индекс; однако /^a.*/
и /^a.*$/
являются более медленными. /^a/
может остановить сканирование после , соответствующее префиксу.
Вы пытались использовать gt вместо> – gpullen