Рекомендации по моделированию Elasticsearch

Недавно я начал работать с Elasticsearch и сейчас сохраняю в нем некоторые данные через Spring Data Elasticsearch.

Я относительно новичок в базах данных NoSQL.

Я хочу знать, как лучше всего смоделировать журнал аудита для пользователя.

В настоящее время я вижу два подхода.

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

Что-то похожее на это

@Document(indexName = "user_audit_log", type = "UserAuditLog")
public class UserAuditLog {

    @Id
    private String uuid;

    private Long userID;

    private String action;

    private String original;

    private String newValue;

    private OffsetDateTime timestamp;
}

И напишите записи аналогично RDBMS. Основное преимущество, которое я вижу в этом подходе, заключается в том, что не нужно беспокоиться о параллелизме записи.

Второй подход заключается в том, чтобы иметь один документ для каждого пользователя. И записи журнала помещаются в список внутри.

Что-то похожее на это.

public class UserAuditLogEntry {
    private String action;

    private String original;

    private String newValue;

    private OffsetDateTime timestamp;

}

@Document(indexName = "user_audit_log", type = "UserAuditLog")
public class UserAuditLog {

    @Id
    private Long userID;

    private List<UserAuditLogEntry> auditLogEntries;
}

Документ должен быть загружен, и коллекция auditLogEntries должна быть обновлена, и вся модель должна быть сохранена снова.

Основным недостатком, о котором я могу думать, является необходимость одновременной защиты от записи.

Какой из них является лучшей практикой в ​​elasticsearch?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
315
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не вопрос для области переполнения стека (вы, вероятно, получите близкие запросы).

Используйте первый. Не только из-за параллелизма, но и зачем хранить эти записи в хранилище данных, если вам не нужны такие вещи, как поиск записей во временном диапазоне или записей, содержащих специальный текст и т. д.? Вы можете сделать это и со второй версией, но представьте, что у пользователя через некоторое время есть 1 миллион записей в журнале, и вы хотите найти особенную. Используя второй подход, поиск всегда будет возвращать весь объект со всеми входами в него.

При добавлении новой записи вам сначала нужно будет прочитать все записи в большом объекте из Elasticsearch, а затем записать их обратно; это будет становиться все медленнее и медленнее не только из-за объема передаваемых данных, но и потому, что все уже существующие записи будут переиндексированы при сохранении измененного документа.

И хотя настройка индексации для вложенного объекта может работать, это намного сложнее, чем при использовании первого решения.

Так что просто сохраните отдельные записи в Elasticsearch, нет абсолютно никаких причин не делать этого.

И если вы хотите использовать причудливые информационные панели, такие как Kibana, это также работает сразу с этим подходом.

Другие вопросы по теме