应用程序背景:我正在处理由客户端和服务器端组成的应用程序。服务器端每5分钟从一些外部API馈送器消耗数据,转换它并将其保存到Neo4j图形数据库中。 客户端通过调用服务器端获取所有存储的数据,并根据接收的数据构建图表:
http://decisionwanted.com/decisions/2/bitcoin
更多保存详情:每次,对于新消费的数据,我都会创建新的 历史值节点 ,并与现有的建立新的关系值 (根)节点:
问题: 服务器端通过应用以下Cypher查询返回所有存储的目前数据:
MATCH (v:Value)-[rvhv:CONTAINS]->(hv:HistoryValue)
WHERE v.id = {valueId}
OPTIONAL MATCH (hv)-[ru:CREATED_BY]->(u:User)
WHERE {fetchCreateUsers}
RETURN ru, u, rvhv, v, hv
ORDER BY hv.createDate DESC
由于每次使用操作后总数据量都在增加,因此查询性能开始降低,延迟开始增加。
问题:
例如:存储了1000个历史值节点。我想只返回每一百个元素,从第1个开始到1000个结束。
因此查询的结果集应包含节点1,100,200,300,400,500,600,700,800,900,1000。
这种方法对我来说很好。唯一的问题是如何告诉Cypher查询:
MATCH (v:Value)-[rvhv:CONTAINS]->(hv:HistoryValue)
WHERE v.id = {valueId}
OPTIONAL MATCH (hv)-[ru:CREATED_BY]->(u:User)
WHERE {fetchCreateUsers}
RETURN ru, u, rvhv, v, hv
ORDER BY hv.createDate DESC
只返回每百个元素?有谁知道怎么做?
答案 0 :(得分:3)
由于您的查询最后使用ORDER BY
,因此Cypher必须生成所有结果行,然后对它们进行排序。如果如问题#2所述,您希望将结果限制在某个时间范围内,则应尽早对其进行过滤,以尽量减少工作量。例如,如果您只对参数化createDate
和startDate
值中的endDate
值感兴趣:
MATCH (v:Value)-[rvhv:CONTAINS]->(hv:HistoryValue)
WHERE v.id = {valueId} AND {startDate} <= hv.createDate <= {endDate}
OPTIONAL MATCH (hv)-[ru:CREATED_BY]->(u:User)
WHERE {fetchCreateUsers}
RETURN ru, u, rvhv, v, hv
ORDER BY hv.createDate DESC
除了执行上述早期过滤之外,以下查询还返回索引0,100,200,...,1000处的行的集合:
MATCH (v:Value)-[rvhv:CONTAINS]->(hv:HistoryValue)
WHERE v.id = {valueId} AND {startDate} <= hv.createDate <= {endDate}
OPTIONAL MATCH (hv)-[ru:CREATED_BY]->(u:User)
WHERE {fetchCreateUsers}
WITH ru, u, rvhv, v, hv
ORDER BY hv.createDate DESC
LIMIT 1001
WITH COLLECT({ru: ru, u: u, rvhv: rvhv, v: v, hv: hv}) AS data
RETURN REDUCE(s = [], i IN RANGE(0, 1000, 100) | s + data[i]) AS result;
LIMIT 1001
子句将data
集合的大小最小化为仅1001行数据(因为索引1000用于行1001)。RANGE(0, 1000, 100)
用于生成感兴趣的行的索引。REDUCE
函数用于在这些索引处生成最终的数据集合。