坦率地说,我很擅长使用Neo4j。 在阅读了大量文档后,我想知道存储访问“日志”的最佳方式是什么,数据类型如时间戳? 例如,我有以下关系: 的 [U:用户] - (访问) - > [P:公园] 我应该为包含多个时间戳的Visited创建列表属性吗? 或者我应该在包含每个唯一时间戳的两个实体之间建立多个“访问”关系? 在两个实体之间生成多个关系似乎是一种开销。 我觉得我在使用这种类型的数据库时缺少一个关键概念。 非常感谢,
答案 0 :(得分:0)
或者我应该在包含每个唯一时间戳的两个实体之间建立多个“访问过的”关系?
生成多个关系很好 - 图形数据库是针对这种工作负载量身定制的,因此他们非常善于有效地处理它。这样,添加和删除新访问非常简单。例如,如果您使用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
方法返回第一个非空值 - 因此,如果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]
有关时间戳的说明。 vanilla Neo4j中没有时间戳。常见的解决方法包括使用epoch time或具有特定格式的字符串,例如ISO 8601。如果您的用例需要以更复杂的方式处理时间戳,请考虑使用conversion methods offered by the APOC library。