Войти Регистрация
Data base

251. Баги на доске, где чек-лист ещё не закрыт

Средняя

Trello выбрал MongoDB ради денормализации: карточка со всеми метками и чек-листом хранится одним документом, а по вложенным полям всё равно можно искать и строить индексы. Произвольных JOIN при этом нет — зато запись быстрая.

В коллекции cards у карточки есть доска board, название name, массив меток labels и чек-лист checklist — массив пунктов {text, done}.

Разработчик открывает доску b1: нужны карточки с меткой bug, у которых остался хотя бы один невыполненный пункт. Верните name и open_items — число невыполненных пунктов, по убыванию open_items, при равенстве — по name. Названия карточек на доске не повторяются.

В работе: Канбан-доски, задачи с подзадачами, заказы с позициями — всё, где дочерние записи лежат массивом внутри документа.

MongoDB · MongoDB 8.0.20

Коллекции

cards — одна карточка — один документ

ПолеТипЧто значит
boardstringдоска
namestringназвание
labelsarray<string>метки
checklistarray<{text, done}>пункты чек-листа

Пример: документы

cards

[
 {
  "board": "b1",
  "name": "Падает экспорт в CSV",
  "labels": [
   "bug",
   "backend"
  ],
  "checklist": [
   {
    "text": "воспроизвести",
    "done": true
   },
   {
    "text": "починить",
    "done": false
   },
   {
    "text": "тест",
    "done": false
   }
  ]
 },
 {
  "board": "b1",
  "name": "Кнопка уезжает на iPhone SE",
  "labels": [
   "bug"
  ],
  "checklist": [
   {
    "text": "скриншот",
    "done": true
   },
   {
    "text": "фикс вёрстки",
    "done": false
   }
  ]
 },
 {
  "board": "b1",
  "name": "Тёмная тема",
  "labels": [
   "feature"
  ],
  "checklist": [
   {
    "text": "макет",
    "done": false
   }
  ]
 },
 {
  "board": "b1",
  "name": "Опечатка в письме",
  "labels": [
   "bug"
  ],
  "checklist": [
   {
    "text": "исправить",
    "done": true
   }
  ]
 },
 {
  "board": "b2",
  "name": "Таймаут вебхука",
  "labels": [
   "bug"
  ],
  "checklist": [
   {
    "text": "логи",
    "done": false
   }
  ]
 }
]

Ожидаемый ответ

[
 {
  "name": "Падает экспорт в CSV",
  "open_items": 2
 },
 {
  "name": "Кнопка уезжает на iPhone SE",
  "open_items": 1
 }
]
Как проверяем Запрос — JSON: имя коллекции и стадии aggregate, как в db.коллекция.aggregate([...]). Выполняем его в браузере движком агрегаций на 4 наборах документов: пример выше и скрытые — с пропущенными полями, null и пустыми коллекциями. Порядок документов важен, порядок полей внутри документа — нет. $out и $merge запрещены.
{"collection": "cards", "pipeline": [ … ]}
массивы поддокументов$filter$sizeзапрос по вложенному полю

Источник: кейс Trello: стек технологий, блог Atlassian, 2012. Условие пересказано своими словами.