Вы можете использовать $strLenCP
в пределах $expr
и некоторую осторожную обработку при обработке массивов:
db.collection.find({
"$expr": {
"$anyElementTrue": {
"$map": {
"input": {
"$reduce": {
"input": "$key.array.arrKey",
"initialValue": [],
"in": { "$concatArrays": [ "$$value", "$$this" ] }
}
},
"in": { "$gte": [ { "$strLenCP": "$$this" }, 5 ] }
}
}
}
})
Если у вас MongoDB старше чем3.6 вместо этого можно использовать $where
:
db.collection.find({
"$where": function() {
return this.key.reduce((o,e) => o.concat(e.array.map(a => a.arrKey)), [])
.some(e => e.length >= 5);
}
})
Оба следуют одному и тому же принципу доступа к внутренним элементам массива путем «объединения» в один массив строк с последующим тестированием этих элементов.чтобы увидеть, соответствуют ли они требованиям к длине.
Следующее необходимо для предотвращения неправильных ответов
ПРИМЕЧАНИЕ : прежде чем кто-либо еще прыгнет сюда и скажет «Эй, ты не можешь просто сделать это:»
db.collection.find({
"$expr": { "$gte": [ { "$strLenCP": "$key.array.arrKey" }, 5 ] }
})
Тогда НЕТ, вы не можете , и причина очень проста - посмотретьпри чем это запись выражения агрегации фактически делает :
db.collection.aggregate([
{ "$project": {
"value": "$key.array.arrKey"
}}
])
Возвращает:
{ "_id" : "id", "value" : [ [ "value" ] ] }
Таким образом, возвращаемое значение "$key.array.arrKey"
НЕ является "строкой""value"
но вместо этого это вложенный массив, как показано выше.Следовательно, уменьшает и конкатенацию массива до одного массива строк, а затем map операция над этими элементами массива для проверки каждого элемента .
Именно поэтому оба выражения агрегации И в выражении JavaScript следуют одному и тому же логическому шаблону.Поскольку "$key.array.arrKey"
видит совершенно иную картину того, что .find({ "key.array.arrKey": { "$exists: true } })
может делать.
Выражения агрегации и операторы запросов работают совсем по-другому .
Отмечая, конечно, что поиск строк длиннее 6
(или любой длины, превышающей фактическую строку):
db.collection.find({
"$expr": { "$gte": [ { "$strLenCP": "$key.array.arrKey" }, 6 ] }
})
вернет поставленный документ в вопросе с ошибкой .
Обратите также внимание, что в этом случае $strLenCP
фактически сравнивает «строковое» представление массива, включая скобки []
ирасстояние.Что, конечно, неверно.