在neo4j中跟踪关系中日志的最佳方式



坦率地说,我对使用Neo4j很陌生。在阅读了大量文档后,我想知道使用时间戳等数据类型存储访问"日志">的最佳方式是什么?例如,我有以下关系:[u:User]-(Visited)->[p:Park]我应该为Visited创建一个包含多个时间戳的列表属性吗?或者我应该在两个实体之间建立多个"已访问"关系,每个实体都包含一个唯一的时间戳?在这两个实体之间生成多个关系似乎是一项开销。我觉得在使用这种类型的数据库时,我错过了一个关键概念。非常感谢,

或者我应该在两个实体之间建立多个"Visited"关系,每个实体都包含一个唯一的时间戳?

生成多个关系很好——图形数据库是为这类工作负载量身定制的,因此它们非常擅长高效地处理它。通过这种方式,添加和删除新访问非常简单。例如,如果您用id标识用户和公园,那么这样的查询就会起作用。

添加新访问:

MATCH (u:User {id: $userId}), (p:Park {id: $parkId})
CREATE (u)-[:VISITED {timestamp: $timestamp}]->(p)

删除访问:

MATCH (:User {id: $userId})-[v:VISITED {timestamp: $timestamp}]->(:Park {id: $parkId})
DELETE v

查询用户的所有时间戳也很容易:

MATCH (:User {id: $userId})-[v:VISITED]->(:Park {id: $parkId})
RETURN collect(v.timestamp)

我应该为Visited创建一个包含多个时间戳的列表属性吗?

属性列表可以在纸上工作,但它会使查询变得非常麻烦:

MATCH (u:User {id: $userId})-[v:VISITED]->(p:Park {id: $parkId})
SET v.timestamps = coalesce(v.timestamps, []) + [$timestamp]

(coalesce方法返回第一个非null值——因此,如果timestamps属性未初始化,它将返回一个空列表。)

当然,这种表示使查询所有时间戳变得更加简单:

MATCH (u:User {id: $userId})-[v:VISITED]->(p:Park {id: $parkId})
RETURN coalesce(v.timestamps, [])

然而,检查是否发生了特定的用户时间戳公园访问变得更加困难,而且(可能)要慢得多:

MATCH (u:User {id: $userId})-[v:VISITED]->(p:Park {id: $parkId})
WHERE $timestamp IN v.timestamps
RETURN v

此外,删除时间戳不再是小事:

MATCH (u:User {id: $userId})-[v:VISITED]->(p:Park {id: $parkId})
SET v.timestamps = [timestamp IN v.timestamps WHERE timestamp <> $timestamp]

关于时间戳的注释香草Neo4j中没有时间戳。常见的解决方法包括使用epoch时间或具有特定格式的字符串,例如ISO 8601。如果您的用例需要以更复杂的方式处理时间戳,请考虑使用APOC库提供的转换方法。

最新更新