Elasticsearch建模最佳实践

时间:2019-06-06 16:48:58

标签: java elasticsearch data-modeling spring-data-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集合,并且必须再次保留整个模型。

我能想到的主要缺点是需要并发写保护。

弹性搜索中的最佳实践是哪一个?

1 个答案:

答案 0 :(得分:1)

不是堆栈溢出范围的问题(您可能会收到关闭请求)。

使用第一个。不仅是因为并发,而且当您不希望在时间范围内搜索条目或包含特殊文本的条目等内容时,为什么还要将这些条目存储在数据存储中?您也可以在第二个版本中执行此操作,但是想象一下,一段时间后该用户有100万个日志条目,并且您想找到一个特殊的条目。使用第二种方法,搜索将始终返回包含所有条目的整个对象。

添加新条目时,您首先必须从Elasticsearch读取大对象中的所有条目,然后将它们写回;这将越来越慢,这不仅是因为传输的数据量很大,而且还因为存储修改后的文档时,所有现有的条目都将被重新索引。

虽然在嵌套对象上设置索引可能会起作用,但比使用第一个解决方案要复杂得多。

因此,只需将单个条目保存在Elasticsearch中,绝对没有理由不这样做。

如果您想使用Kibana这样的精美仪表板,也可以直接使用这种方法。