在neo4j

时间:2017-10-30 18:29:33

标签: neo4j py2neo

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

1 个答案:

答案 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