2014-01-22 67 views
1

假设这种使用情况:的Neo4j /索引属性VS创建不同的节点

“获取2013/05/12 20:00之间全部通过事件2013/05/14 21:00”。

实现这种情况下,Neo4j的是使该属性索引的第一种方式:
事件(startAt:...,ENDAT:...)startAtendAt被索引)

这将导致扫描所有具有与实际查询相对应的属性的事件。

enter image description here

的问题是:

,我刚看到另一种方式是节点遍历比索引属性为交易日期在这种情况下,更好的在性能方面?

回答

5

就性能而言,节点遍历在多级日期时间索引中比在此情况下处理日期的索引属性要好得多?

不,对于此类型的数据结构,日期的索引属性比遍历更具性能。

下面是使用混合方法的详细示例。考虑以下子图,其中elipses表示图中的连续模式。

Multilevel Calendar Index

请看一看https://gist.github.com/kbastani/8519557为完整的日历Cypher支架脚本获取或创建(合并)一个多层次的日期时间指数。这个数据结构允许你从一个日期到另一个日期遍历一系列时间序列的事件。索引属性匹配和遍历的组合是最好的方法,并且在正确建模时是高性能的。

Example Data Model for Time

例如,请考虑以下的Cypher查询:

// What staff have been on the floor for 80 minutes or more on a specific day? 
WITH { day: 18, month: 1, year: 2014 } as dayMap 

// The dayMap field acts as a parameter for this script 
MATCH (day:Day { day: dayMap.day, month: dayMap.month, year: dayMap.year }), 
     (day)-[:FIRST|NEXT*]->(hours:Hour), 
     (hours)<-[:BEGINS]-(shift:Event), 
     (shift)<-[:WORKED]-(employee:Employee) 

WITH shift, employee 
ORDER BY shift.timestamp DESC 

WITH employee, head(collect(shift)) as shift 

MATCH (shift)<-[:CONTINUE*]-(shifts) 

WITH employee.firstname as first_name, 
    employee.lastname as last_name, 
    SUM(shift.interval) as time_on_floor 

// Only return results for staff on the floor more than 80 minutes 
WHERE time_on_floor >= 80 
RETURN first_name, last_name, time_on_floor 

在此查询中,我们都在问数据库“已经在地板上的80个连续分钟或更上了一个什么具体的工作人员天?”轮班被分成连续20分钟的间隔,指向系列中的下一个轮班为CONTINUE或BREAK。

首先,您首先使用索引属性匹配当天。然后,通过遍历日期时间多级索引来扫描当天的连接事件。然后颠倒事件的顺序以获取系列中最近的事件。然后遍历,直到遇到“BREAK”关系。最后,应用time_on_floor大于或等于80分钟的条件。

4

的设计时间线树(尤其是在情况下,当你想要的间隔周期之间寻找)一个更好的办法: here

Cypher支架遍历找到合适的事件会更好,如果你更感兴趣的是找出一段时间间隔内发生的一系列事件。

Neo4j将节点属性存储为链接列表。更多信息:here如果您经历了neo4j存储架构,您将意识到创建独特的关系类型将使您的遍历性能更加明智。