Разберемся на примере
Вот так выглядит документ компании :

$unwindПозволяет принимать документы в качестве входных данных , которые оказывают нормированное поле массива и производят выходные документы, такие , что есть один выходной документ для каждого элемента в массиве. источник

Итак, давайте вернемся к примерам наших компаний и посмотрим на использование этапов размотки. Этот запрос:
db.companies.aggregate([
{ $match: {"funding_rounds.investments.financial_org.permalink": "greylock" } },
{ $project: {
_id: 0,
name: 1,
amount: "$funding_rounds.raised_amount",
year: "$funding_rounds.funded_year"
} }
])
создает документы, содержащие массивы для суммы и года.

Потому что мы получаем доступ к собранной сумме и году финансирования для каждого элемента в массиве раундов финансирования. Чтобы исправить это, мы можем включить стадию раскрутки перед стадией проекта в этот конвейер агрегирования и параметризовать это, сказав, что мы хотим unwindмассив раундов финансирования:
db.companies.aggregate([
{ $match: {"funding_rounds.investments.financial_org.permalink": "greylock" } },
{ $unwind: "$funding_rounds" },
{ $project: {
_id: 0,
name: 1,
amount: "$funding_rounds.raised_amount",
year: "$funding_rounds.funded_year"
} }
])

Если мы посмотрим на funding_roundsмассив, мы знаем , что для каждого funding_rounds, есть raised_amountи funded_yearполе. Итак, unwindбудет для каждого из документов, которые являются элементами funding_roundsмассива, создать выходной документ. Теперь, в этом примере, наши значения - strings. Но, независимо от типа значения для элементов в массиве, unwindбудет создан выходной документ для каждого из этих значений, так что в рассматриваемом поле будет только этот элемент. В случае funding_rounds, этот элемент будет одним из этих документов в качестве значения funding_roundsдля каждого документа, который передается на нашу projectсцену. Результатом этого запуска является то, что теперь мы получаем amountи year. По одному на каждый раунд финансирования для каждой компаниив нашей коллекции. Это означает, что в результате нашего сопоставления было получено множество документов компании, и каждый из этих документов компании приводит к множеству документов. По одному на каждый раунд финансирования в каждом документе компании. unwindвыполняет эту операцию, используя документы, переданные ему со matchсцены. И все эти документы по каждой компании затем передаются на projectсцену.

Таким образом, все документы, в которых спонсором был Greylock (как в примере запроса), будут разделены на количество документов, равное количеству раундов финансирования для каждой компании, которая соответствует фильтру $match: {"funding_rounds.investments.financial_org.permalink": "greylock" }. И каждый из этих результирующих документов затем будет передан нашему project. Теперь unwindсоздает точную копию для каждого документа, который он получает в качестве входных данных. Все поля имеют одинаковый ключ и значение, за одним исключением: это funding_roundsполе, а не массив funding_roundsдокументов, вместо этого имеет значение, которое представляет собой один документ, который представляет собой отдельный раунд финансирования. Итак, компания, у которой есть 4 раунда финансирования, приведет к unwindсозданию 4документы. Где каждое поле является точной копией, за исключением funding_roundsполя, которое вместо того, чтобы быть массивом для каждой из этих копий, вместо этого будет отдельным элементом из funding_roundsмассива из документа компании, который unwindв настоящее время обрабатывается. Таким образом, unwindна следующий этап выводится больше документов, чем он получает на входе. Это означает, что наша projectсцена теперь получает funding_roundsполе, которое, опять же, не является массивом, а представляет собой вложенный документ raised_amountс funded_yearполями и. Таким образом, он projectбудет получать несколько документов для каждой компании, matchвключенной в фильтр, и поэтому может обрабатывать каждый из документов индивидуально и определять индивидуальную сумму и год для каждого раунда финансирования для каждой компании..