Miscellanea VII

Между тем в США столкнулись с ситуацией, к которой приводит сокращение обучения до ввода человеческого ресурса в строй. Иными словами, моряки теперь не умеют ходить по морям, но являются больше операторами чего-нибудь. Вот важная для меня цитата:

Yet many current and former officers say the problem dates back to 2003, when the Navy made severe cuts to SWO’s initial training under the belief the young officers would just learn their trade at sea.

At the same time, the Navy’s growing reliance on technology has eroded basic seamanship skills, former officers say.

Если чуть глаз скосить… не миграция ли программистов в разработчики?


Смешно (ок, не смешно), но одна из самых проблемных тем на собеседованиях (если собеседуется не студент матфака) — таблицы истинности. Редкий разработчик долетит до середины. Хотя, казалось бы, совершенно базовые и обязательные знания. Градус пугливости можно повышать, идя по лесенке вопросов: 1) таблица OR, 2) таблица XOR, 3) таблица XNOR. Следующий коварный вопрос: сколько входов может быть у булевой функции? Вот именно в таком виде и задавать.

Перестал понимать, зачем нужны разработчики, которые не хотят сделать код лучше / правильнее. Ну да, код плохой… Ну да, так однажды сделал кто-то… Ну да, оно не работает… Так возьми и сделай лучше, блин. Ладно ситуации, когда руководитель по рукам бьёт, ему норм такая кака под боком. Но если по рукам не бьют и дают добро на любую инициативу, что мешало? Постоянно что-то мешает таким ребятам. А ответ один и простой: им не надо. Не интересно. Им пофиг. Вот не очень понятно, зачем нужны те, кому пофиг. Если вы такой, вас однажды заменят. Или не заменят, но вы вечно будете сидеть в тёмной норе с одними и теми же норными задачами уровня «выкопать камень, притащить туда».

Хороший пример «реактивной разработки» (когда что-то делается в качестве реакции на взорвавшуюся проблему, а не превентивно) происходит сейчас с прошивкой дронов DJI. Дроны во время работы ходят в сеть мимо юзерских желаний. DJI многократно были пинаемы, но многократно откладывали нежелание юзеров такой фичи в ящик. Что в итоге? В итоге Пентагон запретил дроны DJI. Теперь бойцы рвут жилы, чтобы как можно быстрее сделать offline режим. Хотя, казалось бы, послушай пользователей, подумай, сделай всё вовремя и без убытка.

Есть занятная лакуна в разработчиках. Типовой разработчик делает сервис. Подключает кучу интересных библиотек. В процессе так подхачит. Эдак. Пару баз развернёт. То из исходников соберёт, это (к слову, никак не пойму, почему с таким опозданием Python 3.6.x оказывается в Ubuntu). Вообще всячески развлекается. А потом громом с неба предложение написать мануал по установке сервиса на голую машинку. Мануал, который можно дать другому человеку и не стоять за спиной. Тут-то проза жизни. Страница прозы. Другая. Может, в следующий раз шевельнётся чего в размышлениях. Ибо невероятно легко спихивать всё на админов, конечно же.

Разработчик vs программист

Как ни крути, а приходится как-то делить специальных людей на классы. Если с ролями всё понятно (фронтендер, девопс, админ, бекендер, нок и т.д.) и с приблизительным уровнем тоже (junior, middle, senior, Bozhenka)… есть ещё одно измерение, без введения которого можно не заметить разницу между очень разными специалистами.

Разработчик — тот класс, который почти целиком захватил IT/CS сектор. Считаю их пользователями. Водители. Одни менее опытные, другие более опытные. Совсем продвинутые могут перегнать тачку из Владивостока в Сомали по дну океанов. Знают правила. Разбираются в марках масла. Девопсы-водители даже умеют менять пробитые камеры и продуть свечу, чем восхищают водителей другого пола.
Но основная особенность именно в использовании. Разработчик существует на всём готовом. Готового всё больше. Настали благословенные времена, в которые 99% задач решаются методом «найди нужный кусок кода, почитай мануал (если не остался в душе junior’ом), прикрути клеем с изолентой в свой сервис, иди домой пить пиво». Соответственно, в эту сторону разработчики и развиваются. Водитель какой-нибудь Subaru наизусть знает заправки с хорошим бензином, магазины нужных запчастей, вступает в клубы любителей Subaru, с удовольствием листает мануалы тюнинга. Становится уважаемым субароводом.
Такая практика порождает определённую рабочую психологию (или же разработчиками становятся благодаря ей, не понял пока). Человек не хочет и [уже] не может находить ответы на вопросы категории «как и почему это работает». Как покупатель в магазине, которого не интересует происхождение гречки, латинское название (Fagopyrum esculentum), химический состав, особенности переваривания, агротехника, логистика и прочее. Разработчик хочет купить, сварить, скушать и жить дальше.
Подчеркну важное. Вышеописанное не означает, что разработчик глуп и / или бесполезен. Означает, что он мыслит и действует вполне определённым, пусть и ограниченным качественно образом. Качественно, не количественно. На то, чтобы освоить современный ассортимент «магазинов софтовой гречи», можно жизнь положить, всё равно не хватит.
В крайнем проявлении разработчик относится к специальности без особых эмоций. Работа как работа. Восемь часов отработаю и точка. Мог клерком работать, бумаги перекладывая и печати ставя, а работаю разработчиком. Строчки кода перекладываю и enter нажимаю. Жду вечера, чтобы убежать и заняться чем-нибудь интересным. Таких тоже много.
Разработчики обычно привязаны к одному стеку. Один язык. Один привычный фреймворк. Одна любимая база. Хороший разработчик знает их хорошо. Средненький просто знает.

Программистами считаю другую категорию. Пожалуй, наиболее близки к ним пресловутые хакеры 70-х, для которых естественным было знать всё максимально глубоко и широко в области «как это работает». Продолжая автомобильную аналогию… можно сказать, программист — это механик с образованием физика. Может не знать, как конкретно в данном двигателе прибиты клапаны, но объяснит, зачем они там, что с ними будет и на что их можно заменить без таких же на полке соседнего магазина.
Очень важная (и чуть ли не классообразующая) черта в безумном желании познавать. Знание получается из множества источников, к работе с которыми программист привыкает. Чтение исходного кода. Чтение статей (докторские научные работы тоже причисляем к статьям). Многократные тестовые обстрелы интересного софта. Видео. Разговоры с другими программистами. Мониторинг новостей. Столь любимые мною книги, наконец. Всё это превращается в инструмент построения цельной системы знания, из которой программист может доставать либо явно имеющийся, либо выводимый ответ на любой вопрос.
При всей моей симпатии именно к этому классу… сложные ребята. Их работа подпитана эмоциями, любовью к специальности, к знаниям, к процессу. Им важен интерес. Соответственно, можно здорово промахнуться, поставив на задачу того, кто на бумаге спроектирует великолепный проект, но никогда не доведёт его до релиза (скучно, ведь интереснее было придумать). Также промахиваешься, не контролируя любителей перепробовать буквально всё в поисках оптимальности (и снова не будет релиза годами, ведь сервис может работать на секунду быстрее!). И ещё десятки способов промахнуться, не угадав момент, в который программист считает задачу выполненной, посчитав решением любопытную ему часть.
В крайнем проявлении программисты бесполезны. Если крайнее проявление разработчика можно хотя бы гвозди посадить забивать и гвозди будут забиты, то в случае с программистом даже к молотку не подойдёт. Сначала прочитает про гвозди. Узнает про молотки. Получит седьмое высшее гвоздезабивательное. Напишет пяток научных работ. Разработает теорию влияния фаз Меркурия (ещё и обоснует наличие фаз) на гвоздевую ржавчину. И вообще хорошо проведёт время, но ни один гвоздь забит не будет.
Программисты обычно тяготеют к универсальности. Два-три языка, несколько фреймворков, несколько баз данных. Практика, впрочем, нередко сводится к одному привычному (любимому, интересному) стеку.

Между этими двумя классами и вокруг них есть другие. Переходные или «братские». Но именно «разработчиков» и «программистов» хватает для того, чтобы уместно нанимать и уместно ставить людей на уместные задачи. Разработчики плохо проявляют себя в R&D, также ниочинь, если требуется построить что-то отличное от массового производства. Программисты не успевают себя проявить там, где специализированный разработчик (jQuery-программист) за сутки поднимет дом. Типовой, да, но за сутки и вполне пригодный.

Среди прочего хочется устойчиво донести две важных, мне кажется, мысли.
Во-первых, это не деление на глупых или умных. Было бы слишком примитивно, да и неверно по сути. Пишущие код являются людьми, зачастую очень разными, а люди сложны. Разработчик вполне может однажды стать программистом. Программист может стать разработчиком. С годами у многих меняются внутренние движители. То, что горячо любил вчера, завтра покажется пресным (и программист уходит водить Боинги). То, что ещё вчера пресное, сегодня вдруг раскрывается сотней граней и разработчик усаживается на попу перед изящной архитектурой микропроцессора с мыслью «это лучше клуба по пятницам». Одним не хватает всего одного внешнего импульса (пинка по жопе), чтобы жизнь изменилась. Другие просто пока ещё не нашли себя. Всякое бывает.
Во-вторых, должны быть все. Мир, состоящий из одних лишь разработчиков, не будет двигаться вперёд. Горизонтальное развитие. Вместо того, чтобы создать альтернативные источники энергии, накопаем миллион дырок с нефтью и газом. Мир, состоящий из одних лишь программистов, будет метаться от одной гениальной идеи к другой, в итоге утонет в хаосе. Глуп тот руководитель, что нанимает и применяет только один класс.
Деление достаточно условно и (с точки зрения нанимающего руководителя) больше о том, куда можно применить руки и голову человека. Желательно, прямо сейчас, а не после года обучения и мотивации. Наконец, оно должно помочь понять, что вообще ожидать от сотрудника. Надо ли ругать его за невозможность применить тривиальный алгоритм или за срыв сроков. Надо ли поощрять за банальные с его позиции действия.

Как на практике выяснить, кто есть кто? Допустим, собеседование. Достаточно задавать базовые вопросы, ответы на которые лежат вне плоскости обычной деятельности. Джавистов спросить про GC. Питонистов про GIL. В целом задавать вопросы из области «как работают [словарь, список, память, исключения, циклы]». Обычно для написания сервисов эти знания не нужны. Соответственно, разработчик пожмёт плечами. Раз не нужны, он и не узнавал. Программист будет час рассказывать, вдаваясь в детали из других языков.
Такие вот пирожки с котятами.
Update: во, решил погуглить и обнаружил, что народ давным-давно озадачивается тем же, наиболее близок с первой страницы результатов автор 2010 года.

Женщины в разработке

// на волне истории про Google, сексизм и увольнение.
Надо быть идиотом, чтобы в 2017 году утверждать, что какая-либо умственная профессия натурально подходит одному полу и не подходит другому. Как минимум, подобным утверждениям противоречат множества исключений, бодро кодящих в топовых компаниях.
Попутно надо быть невежественным идиотом, у которого не хватает чего-нибудь важного в голове, чтобы хотя бы погуглить. Тот же ENIAC программировала женская команда. Термин «баг» благодаря женщине (Грейс Хоппер (программист, профессор, контр-адмирал) с интересом смотрит на тех, кто считает разработку мужским занятием). Вся разработческая программа NASA от первых компов до современных спутников усыпана женскими именами. А пацанов, брутально кодящих ARM’ы, должна заинтересовать история ARM processor. И т.д. Я б задолбался тут всё перечислять. Google в помощь.
Так с фига ли? Дальше проговорю очевидные штуки. Очень надеюсь, что они станут очевидными и для вас. Числа буду брать с потолка, т.к. для ряда утверждений просто не нашёл доказательную базу, для ряда вывел с помощью глаз (наблюдать за окружающей жизнью полезно), ряд поленился искать. Воспринимайте в этом тексте числа без ссылок на исследования как иллюстрацию метода. А уж в обилии современной литературы найти фундамент сможете и сами.

Итак, на 100 девочек…
Во-первых, 99 девочек с пелёнок попадают в болото розовых бантиков, кукольных домиков и «ты же девочка». Хотел бы я посмотреть на удачного программиста, которого на всех стадиях формирования мозга и увлечений промывали аксиомами «ты должен играть в куклы», «тебе надо общаться с подружками[, а не паяльником жопу рисовать на текстолите]», «зачем тебе машинка? иди на кухню» и т.д. Как итог, когда пацан (которому не мешали собирать роботов LEGO) уже готов идти в кружок информатики, девочка может даже слова «манипулятор» не знать. Не потому, что глупая. Потому, что росла в глупой среде и с точки зрения технических наук оказалась Маугли. Довольно сложно увлекаться чем-то, к чему с детства нет доступа, знаете ли.
Во-вторых, 50 девочек попадают в пресс жестокой детской среды, уродливо копирующей взрослых. С одной стороны вас давит пункт первый (взрослые). С другой стороны вас давят одноклассники, у которых мозга обычно не хватает на то, чтобы смотреть дальше навязанных ролей. О, ты девочка. Значит, должна быть хихикающей дурой с накрашенными губами, кокетливо смеяться и обсуждать с такой же дурой великие темы «а Васька-то Ольку за трусы схватил, видела? у них любоооовь..!» Кто не обсуждает, тот против нас. Кто против нас, тот страдает. Не все выдерживают.
В-третьих, у 25 девочек нет времени на то, чтобы сидеть над техническими мануалами. На них сбрасывается домашняя работа. Сбрасывается уход за сёстрами/братьями. Сбрасывается «мамина помощница растёт!» и прочее, с чем пацаны часто знакомы лишь на уровне «вынеси мусор, блин, десятый раз прошу». И чёт мало кто понимает, что сложно стать крутым физиком или модным программистом, если у тебя всё свободное детство проходит на кухне. Как итог, девочки умеют борщи варить, а пацаны не могут бутерброд сделать, зато умильно тыкают в «дурочку» пальцем, мол, не может определение байту дать. Да некогда ей было про байт читать, она будущего гения разработки на руках носила, пока мама на двух работах вкалывала.
В-четвёртых, 10 девочек прорвутся и попадут на инженерные факультеты. А там всё та же глупая и недалёкая школота, которая будет тыкать пальцем и повторять нелепость про женщину-физика и морскую свинку. Если девочка красивая, её ещё и это пубертатное стадо задолбит своим пубертатным вниманием. И снова вместо комфортного освоения профессии получается какая-то борьба против всего мира.
В-пятых, 5 девочек получат вышку и начнут искать работу. И… вы уже догадались? В каждом втором месте будет сбегаться половина коллектива, чтобы посмотреть на девушку-программиста. Ааааа! Они бывают! Ааааа! Тёлочка с клавиатурой, гыгыгы. А чё ты на программиста? А давай менеджером. Или тестировщиком. Или дизайнером. Ну ты же девочка, ну какой ты программист? Тоже ни фига не комфорт. Часть сдаётся. Хотела быть программистом, но среда (на сей раз рабочая) продавила. А кто всё-таки твёрдо будет кодить, столкнётся с постоянным фоновым давлением вплоть до оскорблений уровня «слушай, она же баба, ясно, что она ни хрена не знает».
В-шестых, 33 девочки в наиболее активный период жизни (20..35 лет) становятся родившими женщинами. Тем, кого миновало, опишу кратко: человек напрочь вырубается из жизни на пару лет минимум. Сначала чудеса беременности, затем малявка. За эти два года профессионально девочка отбрасывается назад чуть ли не на пять лет (хотя бы потому, что голова постоянно была занята пелёнками, а рот сюсюканьем и «спи, мой хороший, засыпай»), которые нагнать ни фига не просто. Тем, кто считает, что в декрете лафа и можно кодить в удовольствие, попутно обзирая все новинки индустрии… удачи.

Также мне всегда было любопытно… Вот мужской особь в момент сравнения себя с девушкой или в момент размышления «чёт мало женщин-программистов в истории и вокруг меня» хоть на секунду задумывается о том, а почему, собсно? Почему ещё сто лет назад подвигом было в вуз поступить (откровением для иных будет известие о том, что так было во всём мире, а не токмо лишь в лапотной России)? И достаточно ли ста лет для того, чтобы пещерное отношение изменилось на действительно равное? И стал бы программистом этот размышляющий, если бы его с детства долбили так, как девочек? Не всегда явно. Не всегда грубо. Но каждый день. Сто дней. Тысячу. Десять тысяч.
Или вот хорошо бы поразмыслить о том, не является ли кругозор такого особя резко ограниченным? Если отойти на шажок, получается смешное. Если девочки с детства оказываются в интеллектуальной IT-провинции, от чего и рассуждают порою о разработке никак, то IT-сексисты зачастую в такой же провинции сидят уже физически и судят мир по своему гаражу: «У меня (Главнейшего CTO Великой Софтварной Компании из меня и друга Васи) в окружении девочек нет, значит, они от природы к программированию не годятся. Приходила как-то Маня из соседнего подъезда, не смогла даже компилятор запустить, бабы дуры». Нет, дорогой. В больших конторах девочек вовсе не мало. И многие из них заметно толковее, чем большинство окружающих штанов (хотя бы потому, что им для профессии пришлось усилий приложить в разы больше, чем). Программисты, архитекторы, админы, безопасники. Суждение по своему гаражу примерно равно суждению о количестве женщин-автоводителей на дорогах по статистике деревни Гадюкино. В Гадюкино их будет мало. В Москве порою на красный светофор подряд пять-шесть женщин выстраиваются с одиноким мужиком в хвосте.

Вот как-то так. Сумбурно, набросками, но пара основных векторов должна быть понятна. Заодно считаю, что каждая волна яростных обсуждений подобных новостей доказывает и показывает очередное очевидное: «разработчик» и «программист» вовсе не синонимы «умного человека».

Не используйте MongoDB

Раз за разом встречаю case, в котором разработчики сначала выбрали MongoDB, а спустя 3..5 лет привычно слизывают иголки кактуса. При этом после стольких лет эксплуатации миграция в другую БД будет ещё большим кактусом, потому… так и живут, в общем.
Так вот, если выбор MongoDB вам кажется хорошей идеей (в контексте большого, живущего долго и обильно сервиса), подумайте ещё раз. И ещё. И ещё раз пять, обсудив желание с теми, кто уже получил достаточно долгий опыт. Убедитесь, что вы и в самом деле понимаете, во что вляпываетесь. Только тогда используйте.
А если вы привыкли к инструментам и возможностям большой тройки RDBMS (Oracle, PostgreSQL, MySQL), откажитесь от «хорошей идеи» сразу, минуя стадию размышлений и обсуждений.

Сначала о хорошем.
MongoDB отлично подходит для хранения и извлечения древовидных структур данных. Иначе говоря, ровно для того, от чего первоначально поднялся hype — откуда-то прилетает развесистый JSON, а вы его целиком после минимальной конвертации фигак-с в базу, затем целиком фигак-с из базы. Пишется довольно быстро, забирается ещё быстрее. Уря-уря.
А вот дальше всё не так хорошо. Накидаю разбросом.

Умеете ли вы и ваши разработчики жить в условиях анархии? Это когда ограничений нет не только у гениальности и сознательности, но также у глупости, невежества и пофигизма. У MongoDB нет схемы на уровне базы данных. В терминах RDBMS… скажем, у вас таблицы без FK, триггеров, без типов данных. Зато есть разработчики, которые хотят на ручки и смузи, чтобы было меньше работы. Скучной, нудной, требующей кропотливости и тщательности. Ну не любят нежные зайки таблицы проектировать и по крупицам что-нибудь проверять. А тут такая щедрая MongoDB.
Прошло 3 года. У вас 50GB data size, 50 collections и 100M objects. Вася уволился в первый год. Петя ушёл в запой на второй год. Игнат в третий год устроил рефакторинг (лучше б пельмени лепил). Вопреки всем рекомендациям и увещеваниям у коллекций есть «виртуальные» связи между собою (те же foreign keys, но без них). Угадайте, насколько целостными являются данные? Угадайте, какие варианты значений могут быть у какого-нибудь поля (попутно угадайте, всегда ли это поле вообще есть)? Именно угадайте. А если вам не нравится угадывать количество дыма без огня в production, вы озадачитесь мегатонной кода, который обойдёт каждый документ, заглянет в каждое поле и сверит хотя бы варианты «у нас нет яблока в ведре гвоздей». Прогноз результата зависит от того, насколько вы доверчивы и наивны. Разработчики обязательно всё делали хорошо, правильно и не в режиме «быстро-быстро говнякаем, нам надо срочно в прод». Конечно. Как иначе-то.

Любите ли вы транзакции? Нет? MongoDB тоже не любит. Безусловно, можно подкрасить глаза кровью и на основе Atomicity and Transactions соорудить что-нибудь похожее, но к нормальным транзакциям вы только приблизитесь.
Чревато это весьма занятными эффектами, когда в процессе записи чего-нибудь в две разные коллекции ваше приложение ляжет. Или MongoDB ляжет. Или сеть пропадёт. В общем, произойдёт событие, которое прервёт запись десяти примет преступника в розыске на второй примете. Есть люди, которых это не волнует. Как привык уже думать, у каждого своя трактовка качества продукта. Зато те, кто озадачится темой «чё дальше делать», обнаружат, что механизмов rollback’а нет. И либо те же разработчики (вспомним, эти ребята не хотели тратить время на рутину) будут костылить в приложении откаты и докаты данных с попутной проверкой целостности, либо живите на мине с часиками. Однажды стопудово рванёт.

Выразительность языка запросов в MongoDB несколько хромает. Как и эстетика. Верю, что кому-нибудь может нравиться {size: {$ne: 0}} вместо size <> 0, но общего с такими людьми иметь не хочется.
Ладно, эстетика. Самый сладкий צימעס в том, как удобно работать с большими запросами. У вас адовый JSON на экран. Месиво из фигурных скобок, долларов и двоеточий. Удобно грепать. Удобно парсить глазами. Удобно писать меленькие конструкторы для запросов (как всё ещё пишут иногда для SQL). Шучу. Удобство нулевое.
Что любопытно, несколько лет назад в сети был движняк, показывающий примеры, как няшно выглядят запросы MongoDB в сравнении с SQL. Мол, вот тут одна строчка вместо этого ужас-ужас, пользуйтесь нашим сахарком. И да, в тех примерах вроде бы всё верно. Вот только существует масса примеров с обратной стороны, когда привычный и семантически эквивалентный SQL-запрос превращается в неудобоваримый ужас-ужас.

Недавно один товарищ не смог ответить на простой вопрос: что такое [де]нормализованные данные? Так вот разницу между этими состояниями легко можно познать в процессе миграции из одного в другое. Нормализованные (если поняли, что несколько ошиблись в выбором RDBMS и надо другое) катнуть в какую-нибудь NoSQL достаточно просто. А вот из MongoDB в SomethingSQL… ха-ха, в цирке смешно уже не будет никогда. Нет, правда. Меня всякий раз так радуют восхищённые ребята, лишившие себя нужды вносить строгость в виде схем данных, проверок и прочего. Счастья им и здоровья, ждёт море открытий чудных.

Оно жрёт память. Как не в себя. Что RAM, что HDD/SSD. И если на винт ещё как-то ладно бы (всё равно бывает грустно, впрочем), то куда ж ты, зараза такая, перевариваешь оперативку? Начинаешь гуглить. Начинаешь читать совсем уж дебри мануалов. И обнаруживается, что даже WiredTiger всё, везде и всегда кладёт в RAM. Ну а чё? Кто в школу для взрослых ходил, знает, что это прям вот почти самая быстрая доступная память (не в регистры процессора же класть), давайте использовать её. Использует. Так, что у OOM killer порою глаз дёргается. Я, конечно, могу у WT ограничить cacheSizeGB, но станет ли MongoDB хорошо? Обжора, которому желудок ушили, вряд ли радостен.
На дисках, всё-таки к слову, тоже могло быть шоколаднее. Живёт базка. Кушает винт. Кушает, кушает. Решаете вы в коллекции на 500M документов грохнуть половину. Грохаете. Уря? Неть. MongoDB не отпустит место на винте. Чтобы отпустила, надо выполнить compact, который блокирует всё, до чего дотянется. Запланируйте даунтайм всего, это же так интересно.

Отдельное удовольствие причиняет поиск и устранение причин, по которым запрос работает медленно. Тут не могу удержаться и не упомянуть прекрасный принцип, по которому WiredTiger решает, как всё-таки выполнять запрос (индексы и т.д.) — он его сначала выполняет.
Так вот. Даже если предположить, что вы научились правильно читать результат explain, дальше-то что? Если в RDBMS особенно упорные бойцы вспомнят реляционную алгебру, достанут пыльный том Дейта и пятистраничный запрос зажмут в тиски оптимизации, то MongoDB-бойцы как выкрутятся? Обычно выкручиваются прям вот бодро. Сначала создают дополнительные индексы. Ну вдруг поможет. Не помогает. Потом разбивают запрос на несколько запросов (один фиг привычно по временам, когда в MongoDB ничего близко рядом с JOIN не было). Не помогает. Потом дробят свои милые толстеееенные документы с десятками уровнями вложенности на менее вложенные. Чуть-чуть помогает, но подозрительно напоминает схему RDBMS. Потом топятся в ближайшем пруду.
Ибо запихнуть вековые деревья в базу ума большого не надо. А вот обеспечить быстрый поиск с какой-нибудь агрегацией по этим деревьям — оно порою до кандидатских доходит. Но вы же хотели не кандидатскую, а пыщ-пыщ и ололо, да?

В финале не могу пройти мимо механизма локов. Очень советую почитать FAQ: Concurrency, очень. Обратите внимание на ситуации, в которых лочится вся база. Прочтите страницу ещё раз. Потом обратите внимание на то, как лочатся документы (они ведь у вас толстенькие и вы частенько внутри документа добавляете / удаляете, да?). Ещё раз перечитайте. И ещё. До полного просветления. Даже пересказывать не буду, это надо пробовать лично.

Существуют проекты, у которых получилось приготовить MongoDB правильно, при этом в базе прям вот хотя бы middle data, над которой middle load. Там диктатура, сплошь настоящие senior’ы и всё по заветам. Такие проекты рапортуют об успехах, хоть сейчас разводись и женись на MongoDB. Но чёт вот наблюдение за действительностью (от личного опыта до яростных репортов в рассылках) показывает, что в общем случае MongoDB сначала надо учиться готовить. Учиться истово, системно, долго. С умным анализом, с прогнозами в горизонт до пяти лет. Тут можно закрыть глаза и пофантазировать о том, как разработчики читают учебники с мануалами, грызут курсы MDBU, да ещё и сертификацию сдают… Ага.
Уф. Ну вроде по верхам вот так. Удачи отважным.