Операторы $where¶
Пары типа «ключ/значение» являются довольно выразительным способом запроса, но есть запросы, которые они не могут представлять. Для запросов, которые не могут быть выполнены каким-либо другим способом, существуют операторы $where, позволяющие выполнять произвольный код на языке JavaScript как часть вашего запроса. Это позволяет вам делать (почти) все, что угодно, в рамках запроса. В целях безопасности использование операторов $where должно быть строго ограничено или исключено. Конечным пользователям никогда не следует разрешать использовать произвольные операторы $where.
Наиболее распространенным случаем использования оператора $where является сравнение значений двух ключей в документе. Например, предположим, у нас есть документы, которые выглядят так:
1 2 | |
Мы хотели бы вернуть документы, где любые два поля одинаковы. Например, во втором документе spinach и watermelon имеют одно и то же значение, поэтому мы бы хотели, чтобы этот документ был возвращен. Маловероятно, что в MongoDB когда-либо появится условный оператор для этого, поэтому можно использовать оператор $where:
1 2 3 4 5 6 7 8 9 10 11 | |
Если функция возвращает значение true, документ будет частью набора результатов; если она вернет значение false, этого не произойдет.
Запросы с помощью оператора $where не следует использовать без крайней необходимости: они намного медленнее, по сравнению с обычными запросами. Каждый документ необходимо преобразовать из формата BSON в объект JavaScript, а затем прибегнуть к оператору $where. Индексы здесь также нельзя применять. Следовательно, вы должны использовать оператор $where только тогда, когда нет другого способа выполнить запрос. Можно сократить снижение производительности, используя другие фильтры запросов в сочетании с $where. Если это возможно, индекс будет использоваться для фильтрации на основе операторов, отличных от $where; оператор $where будет применяться только для точной настройки результатов. В MongoDB версии 3.6 был добавлен оператор $expr, позволяющий использовать выражения агрегации на языке запросов MongoDB. Он быстрее, чем $where, поскольку не выполняет код на JavaScript и рекомендуется в качестве замены этого оператора, где это возможно.
Еще одним способом выполнения сложных запросов является использование одного из инструментов агрегации.