Другим интересным способом является использование $ redact , который является одной из новых функций агрегации MongoDB 2.6. Если вы используете 2.6, вам не нужно развязывать $ unwind, что может вызвать проблемы с производительностью, если у вас большие массивы.
db.test.aggregate([
{ $match: {
shapes: { $elemMatch: {color: "red"} }
}},
{ $redact : {
$cond: {
if: { $or : [{ $eq: ["$color","red"] }, { $not : "$color" }]},
then: "$$DESCEND",
else: "$$PRUNE"
}
}}]);
$redact
"ограничивает содержимое документов на основе информации, хранящейся в самих документах" . Таким образом, он будет работать только внутри документа . Он в основном сканирует верхнюю часть документа на дно и проверяет, совпадает ли это с вашим if
условием, которое находится в $cond
, если есть совпадение, оно либо сохранит содержимое ($$DESCEND
), либо удалит ($$PRUNE
), .
В приведенном выше примере первый $match
возвращает весь массив shapes
, а $ redact привязывает его к ожидаемому результату.
Обратите внимание, что {$not:"$color"}
необходимо, так как он также сканирует верхний документ, а если $redact
не находит поле color
на верхнем уровне, это вернет false
, которое может разделите весь документ, который мы не хотим.
Зависит от архитектуры.% rip содержит либо текущую исполняющую команду, либо следующую команду, которая должна быть выполнена. Здесь вы добавили точку останова до 0x4017ec, что означает, что следующая команда, которая должна быть выполнена, равна 0x4017ec. Но% rsi будет загружаться только после выполнения первой инструкции. К тому времени% rip уже обновился, чтобы указать на следующую инструкцию.
%rip
. На x86-64 это ни на что не зависит; это всегда начало следующей инструкции, потому что именно так она определена для работы в ISA x86. – Peter Cordes 11 November 2016 в 22:28