假设我有两种类型的节点:服务器和:客户端。
(Client)-[:CONNECTED_TO]->(Server)
我想找到按年龄排序连接到某个服务器的女性客户端。
我做了这个
Match (s:Server{id:"S1"})<-[:CONNNECTED_TO]-(c{gender:"F"}) return c order by c.age DESC
执行此操作后,将遍历链接到“我的服务器”节点的所有客户端节点以查找最高年龄。 有没有办法在性别和年龄属性上索引客户端节点以避免完整扫描?
答案 0 :(得分:2)
您可以在:Client(gender)
上创建索引,如下所示:
CREATE INDEX ON :Client(gender);
但是,您的特定查询可能会从:Server(id)
创建索引中受益更多,因为可能有很多女性客户,但可能只有一个Server
具有该ID。所以,你可能想要这样做:
CREATE INDEX ON :Server(id);
但是,更好的是,如果每个Server
都有一个唯一的id
属性,您应该创建唯一性约束(它也会自动为您创建索引):
CREATE CONSTRAINT ON (s:Server) ASSERT s.id IS UNIQUE;
目前,neo4j不使用索引来执行排序,但有一些APOC procedures支持它。但是,这些过程不支持按降序返回结果,这正是您想要的。因此,如果您确实需要为此目的使用索引,则解决方法是向minusAge
节点添加额外的Client
属性,其中包含age
属性的负值。如果这样做,那么首先创建一个索引:
CREATE INDEX ON :Client(minusAge);
然后使用此查询:
MATCH (s:Server{id:"S1"})<-[:CONNNECTED_TO]-(cl:Client {gender:"F"})
CALL apoc.index.orderedRange('Client', 'minusAge', -200, 0, false, -1) YIELD node AS c
RETURN c;
该过程的第3个和第4个参数用于您要用于匹配的最小值和最大值(针对minusAge
)。第5个参数应该是false
用于您的目的(实际上当前被实现忽略)。最后一个参数用于LIMIT
值,-1
表示您不需要限制。
答案 1 :(得分:1)
如果这是您经常做的请求,那么您可能希望将该数据写出来。正如您所经历的那样,该查询可能非常昂贵,并且您获得的客户越多越好,因为事实上,必须检索所有连接的节点并进行属性检查/比较运行在他们身上。
作为解决方法,您可以在修改其年龄数据时向客户端添加其他连接。
作为建议,您可以创建Age节点并为最早的客户创建MATURE关系。
(:服务器)LT - [:CONNNECTED_TO] - (:客户机) - [:成熟] - GT;(:年龄)
您可以为所有年龄段执行此操作,并根据需要在Age节点(具有索引/唯一年龄属性)上运行查询。如果您有100,000个客户,但只对按年龄排序的前100名感兴趣,则无需获得所有客户并订购它们......这实际上取决于您的用例和客户端应用程序。
虽然这当然不是一个好的模式,但我已经看到它在生产中起作用,并且是我在不同生产环境中表现良好的唯一解决方法。
如果这个答案没有解决你的问题(我也很喜欢使用年龄属性),我希望它至少能让你知道下一步该怎么做。