Отчетность в MongoDB: индивидуальная комбинация аргументов в запросах - PullRequest
2 голосов
/ 26 марта 2020

Что мы хотим сделать

В нашем приложении клиенты могут создавать свои собственные отчеты (CSV, Excel, PDF). В приложении они могут объединять до 30 полей для фильтрации и до 20 полей для индивидуальной сортировки (как c & des c). Предварительный просмотр сразу показывается.

История и будущее

Мы разрабатываем и запускаем приложение уже несколько лет. В прошлом мы использовали No Sql RavenDB 3.5, и было очень легко поместить все данные в индекс. Запросы на поля не было проблемой, и результат был довольно быстрым. Например, предварительный просмотр 20 пользовательских отсортированных и отфильтрованных результатов занял менее секунды.

Для последующего продукта мы начали переходить на MongoDB из-за некоторых проблем с RavenDB в прошлом. MongoDB был нашим первым выбором, потому что мы предпочитаем No Sql (легкая настройка, отсутствие ORM, кластер, производительность, стабильность) и большое сообщество и поддерживаемый драйвер. NET. Мы сделали простой PO C во время оценки, и все, кажется, работает нормально. Может быть, это было слишком просто.

Как выглядят наши данные?

Нам нужно запросить более 50 миллионов документов в одной коллекции, и ее структура выглядит следующим образом:

public class Customer {
    public Metadata Metadata { get; set; }

    [BsonId]
    [BsonRepresentation(BsonType.ObjectId)]
    public string Id { get; set; }
    [BsonRepresentation(BsonType.ObjectId)]
    public string PersonId { get; set; }
    public int OrderIndex { get; set; }
    public DateTime EventTime { get; set; }
    public string[] Scopes { get; set; }  // hierarchical data e.g.: 12.345.678 or 12.340.000
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Sex { get; set; }  // male or female or unknown   
    public string[] Tags { get; set; }
    public bool IsLocked { get; set; }
    public Address[] Addresses { get; set; }
    public int? SomeAmount { get; set; }
    public Relation[] Relation { get; set; }
}

Это выдержка из текущего состояния (проекции) клиента. Мы обрабатываем тысячи событий изменений в день и сохраняем состояние в коллекции. В нашей реальной структуре данных у нас более 40 свойств. Структура данных выглядит очень похоже на старое приложение. Фактически, это должно облегчить миграцию.

Сценарии и проблемы использования

Мы предлагаем пользовательский интерфейс, содержащий до 30 полей, которые можно комбинировать, сортировать и оценивать.

Возможные случаи использования:

  1. Поиск всех лиц старше 30 лет и мужчин, отсортированных по фамилии AS C, FirstName AS C, DateOfBirth AS C
    • Запрос: DateOfBirth + Sex; Сортировка: LastName, FirstName, DateOfBirth
  2. Найти всех людей, живущих в Нью-Йорке, с тегом 'funny', отсортировано по фамилии DES C , Имя AS C, DateOfBirth DES C
    • Запрос: Теги + Адрес; Сортировка: DateOfBirth
    • Внимание : порядок сортировки изменен. Адрес находится в массиве.
  3. Найти всех заблокированных лиц, отсортированных по SomeAmount DES C
    • Запрос: IsLocked ; Сортировка: SomeAmount

Как видите, существует несколько комбинаций. Поэтому мы не можем использовать один индекс только из-за следующих ограничений :

  • строгого порядка полей в составном индексе ( см. )
  • Максимум. 32 поля в составном индексе
  • смешанные порядки сортировки полей в индексе ( см. )
  • в одной коллекции может быть не более 64 индексов (в настоящее время нет проблем)

Сводка

  • Всего документов: 50 миллионов
  • Средний размер документа: 3 КБ
  • Свойства:> 40 (включая вложенные типы и несколько массивы)
  • Запрашиваемые поля: ок. 30 (может быть больше)
  • Свободно сортируемые поля: до 20 в любой комбинации и направлении (ASC / DES C)

Технические требования

  • . NET Core
  • MongoDB. NET Драйвер

Вопросы

  1. Что мы можем сделать для запроса 1-n полей в произвольной сортировке приказ?
    • Несколько индексов в каждом порядке полей? Хм, кажется, очень дорого (диск, производительность) и не забудьте: макс. 64 индекса на коллекцию!
  2. Что делать, если наши клиенты выполняют 40 отчетов одновременно?
    • Сортировка выполняется полностью в оперативной памяти, что может привести к значительному снижению производительности. Что такое хорошая стратегия для обработки такого рода нагрузки?
  3. Что мне делать, если нам нужно запросить более 32 полей?
    • Добавить несколько индексов и использовать пересечение индексов ? Это работает для всех видов комбинаций?
    • Разделить наш документ на несколько частей и использовать ссылки, хранящиеся в другой коллекции? Чем мы должны работать с $ lookup . Хм, это, вероятно, не очень хорошо работает.
  4. Является ли MongoDB подходящей базой данных для таких сложных запросов / отчетов?
    • Как видите, мы долго думали, но, кажется, ничто не соответствует нашим потребностям.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...