Neo4j/Indexed属性VS创建不同的节点

Mik*_*378 1 neo4j graph-databases cypher

我们假设这个用例:

"获取所有传递的事件2013/05/12 20:002013/05/14 21:00".

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

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

我刚读过的其他方式:

在此输入图像描述

问题是:在这种情况下,节点遍历在性能方面要好于处理日期的索引属性吗?

Sum*_*rma 5

设计时间线树的更好方法(特别是在你想要在间隔期间搜索的情况下): 这里

如果您对在一个时间间隔之间发现一系列事件更感兴趣,Cypher遍历找到正确的事件会更好.

Neo4j将节点属性存储为链表.更多信息:这里如果您通过neo4j存储架构,您将意识到创建独特的关系类型将使您的遍历性能更好.


Ken*_*ani 5

在性能方面,节点遍历要比在这种情况下处理日期的索引属性好得多(在多级日期时间索引中)吗?

不,日期的索引属性比这种类型的数据结构的遍历更具性能.

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

多级日历索引

请查看https://gist.github.com/kbastani/8519557,了解获取或创建(合并)多级日期时间索引的完整日历Cypher脚本.此数据结构允许您从一个日期遍历到另一个日期,以获取时间序列的一系列事件.索引属性匹配和遍历的组合是最佳方法,并且在正确建模时具有高性能.

时间的示例数据模型

例如,请考虑以下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
Run Code Online (Sandbox Code Playgroud)

在这个查询中,我们询问数据库"在特定的一天,连续几分钟或更长时间内,工作人员在场的情况是多少?" 将班次分成20分钟的连续间隔,指向系列中的下一个班次为CONTINUE或BREAK.

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