Как указано, $where
- хороший вариант, когда вам не нужно продолжать логику в конвейере агрегации.
Но если вы это сделаете, используйте $redact
, с $map
, чтобы преобразовать «значение» в массив и использовать $setIsSubSet
для сравнения. Это самый быстрый способ сделать это, так как вам не нужно дублировать документы с помощью $unwind
:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": { "$setIsSubset": [
{ "$map": {
"input": { "$literal": ["A"] },
"as": "a",
"in": "$value"
}},
"$array"
]},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
$redact
Оператор конвейера позволяет обрабатывающий логическое состояние в $cond
и использует специальные операции $$KEEP
«держать «документ, в котором логическое условие истинно, или $$PRUNE
« удалить »документ, в котором условие было ложным.
Это позволяет работать как $project
с последующим $match
, но на одном этапе трубопровода, который является более эффективным.
Учитывая, что это собственные закодированные операторы, а не JavaScript, то это, скорее всего, «самый быстрый способ выполнить ваш матч». Таким образом, если вы используете версию MongoDB 2.6 или выше, то именно так вы должны это делать, чтобы сравнивать эти элементы в вашем документе.
Я не пробовал это, но я думаю, что вы, вероятно, хотите '$ elemMatch' (см [документы] (http://docs.mongodb.org/manual/reference/operator/query/elemMatch/# op._S_elemMatch)), а не '$ in' - вы хотите проверить, является ли значение массивом, а не является ли массив значением! – DNA
Вам действительно нужно вернуться и посмотреть на этот вопрос, так как любой, кто предложил '$ unwind', дал вам наихудший возможный ответ на производительность, который вы могли бы реализовать в своем коде. Есть гораздо лучшие альтернативы. –