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

249. Открытые задачи организации в мультитенантной коллекции

Лёгкая

Яндекс Трекер жил по схеме «одна организация — одна база» и дошёл примерно до 70 кластеров MongoDB. Их свели в 7: пять мультитенантных и два выделенных. Чтобы данные организаций не смешивались, в первичный ключ добавили идентификатор организации: _id стал документом {orgId, id}.

В коллекции issues у задачи есть очередь queue и статус status — одно из open, inProgress, closed. Руководитель организации org-1042 открывает отчёт: сколько незакрытых задач (open и inProgress) в каждой очереди.

Верните queue и open_issues по убыванию open_issues, при равенстве — по queue по алфавиту. Очереди без незакрытых задач не нужны.

В работе: SaaS, где данные клиентов делят одну коллекцию: трекеры, CRM, конструкторы сайтов.

MongoDB · MongoDB 8.0.20

Коллекции

issues — одна задача — один документ, общая коллекция для всех организаций

ПолеТипЧто значит
_id.orgIdstringорганизация
_id.idintномер задачи внутри организации
queuestringключ очереди
statusstringopen / inProgress / closed

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

issues

[
 {
  "_id": {
   "orgId": "org-1042",
   "id": 1
  },
  "queue": "SUPPORT",
  "status": "open"
 },
 {
  "_id": {
   "orgId": "org-1042",
   "id": 2
  },
  "queue": "SUPPORT",
  "status": "inProgress"
 },
 {
  "_id": {
   "orgId": "org-1042",
   "id": 3
  },
  "queue": "DEV",
  "status": "open"
 },
 {
  "_id": {
   "orgId": "org-1042",
   "id": 4
  },
  "queue": "DEV",
  "status": "closed"
 },
 {
  "_id": {
   "orgId": "org-1042",
   "id": 5
  },
  "queue": "SUPPORT",
  "status": "closed"
 },
 {
  "_id": {
   "orgId": "org-1042",
   "id": 6
  },
  "queue": "HR",
  "status": "inProgress"
 },
 {
  "_id": {
   "orgId": "org-7",
   "id": 1
  },
  "queue": "SUPPORT",
  "status": "open"
 },
 {
  "_id": {
   "orgId": "org-7",
   "id": 2
  },
  "queue": "DEV",
  "status": "open"
 }
]

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

[
 {
  "open_issues": 2,
  "queue": "SUPPORT"
 },
 {
  "open_issues": 1,
  "queue": "DEV"
 },
 {
  "open_issues": 1,
  "queue": "HR"
 }
]
Как проверяем Запрос — JSON: имя коллекции и стадии aggregate, как в db.коллекция.aggregate([...]). Выполняем его в браузере движком агрегаций на 4 наборах документов: пример выше и скрытые — с пропущенными полями, null и пустыми коллекциями. Порядок документов важен, порядок полей внутри документа — нет. $out и $merge запрещены.
{"collection": "issues", "pipeline": [ … ]}
составной _idточечная нотация$match$groupмультитенантность

Источник: кейс Яндекса: Яндекс Трекер свёл ~70 кластеров MongoDB в 7 мультитенантных. Условие пересказано своими словами.