【问题标题】:How to use both node and relationship auto-index in cypher?如何在密码中同时使用节点和关系自动索引?
【发布时间】:2025-12-27 12:15:06
【问题描述】:

我有问题,你能帮帮我吗?

在我真正的 neo4j2.1.3 中,有大量的节点和关系。所以我必须使用自动索引来提高性能。

例如:节点自动索引的属性键“person_name”、“hotel_name”。和 'inTime' 用于关系自动索引。

然后,我创建数据:

create (:Person {person_name:'p1'})
create (:Person {person_name:'p2'})
create (:Hotel {hotel_name:'h1'} )
create (:Hotel {hotel_name:'h2'} )

start p=node:node_auto_index('person_name:p1'),h=node:node_auto_index('hotel_name:h1')
create (p)-[:STAY_IN {inTime:'20140520'}]->(h)

start p=node:node_auto_index('person_name:p1'),h=node:node_auto_index('hotel_name:h2')
create (p)-[:STAY_IN {inTime:'20140522'}]->(h)

start p=node:node_auto_index('person_name:p2'),h=node:node_auto_index('hotel_name:h1')
create (p)-[:STAY_IN {inTime:'20140510'}]->(h)

接下来,我输入这个密码:

start p=node:node_auto_index('person_name:p1'),
      r=relationship:relationship_auto_index('inTime:[20140501 TO 20140530]')  
match (p)-[r]-(h) return p,r,h

我只想检索“p1”所在的关系。但上面的密码返回 p1 和 p2 的关系。为什么?

我们将不胜感激。

【问题讨论】:

    标签: indexing neo4j cypher


    【解决方案1】:

    对于这种用例,我根本不会使用自动索引,我也认为不需要索引关系。您想要回答的问题基本上是“在 t_min 到 t_max 的时间范围内给我 p1 在任何酒店的住宿吗?”。

    创建架构索引以快速查找起点,即相关人员:

    CREATE INDEX ON :Person(person_name)
    

    您的查询将如下所示:

    MATCH (p1:Person {person_name:"p1"})-[stay:STAY_IN]->(hotel)
    WHERE stay.inTime>=t_min AND stay.inTime<=t_max
    RETURN stay, hotel
    

    Neo4j 中的索引应该只用于识别查询的起点。一旦你在图表中,只需关注关系并尽量避免后续的索引查找,比如对关系的索引搜索。

    在您的代码中,第二个索引查询将返回给定时间范围内任何人的所有停留。这用于与p 的交叉产品,这就是为什么你也得到p2

    【讨论】:

    • 嗨,@Stefan Armbruster,感谢您的回复。你看我说的。但我的情况并不是那么简单。我已经尝试过架构索引。但它不支持范围查询。并且不支持模糊搜索。它仅用于完全匹配。例如:如果我为属性键“person_name”和“person_birthday”创建了 2 个索引:如果我键入以下查询,则创建索引 ON :Person(person_name) 创建索引 ON :Person(person_birthday):match (p:Person) where p .person_name='Mike*' return p match (p:Person) where p.person_birthday > '19800501' return p 架构索引不起作用。
    • 让我们在我的真实案例中回到前面的问题,考虑一下:如果neo4j db中有millons人员节点,并且每个节点也有millons关系。所以我该怎么做?再次感谢您的帮助。
    • 我很确定,如果您将日期保存为整数而不是字符串,您可以使用范围执行匹配,它将使用索引。 match (p:Person) where p.person_birthday &gt; 19800501 return p。就模糊搜索而言,我通常推荐使用 Elasticsearch。它会做得更好,让 Neo4j 做它最擅长的事情。
    • 在这种情况下你需要使用自动索引。
    • 谢谢。 @subvertallchris 不久前,我有一个测试: match (p:Person) where p.person_birthday > 19800501205000 return p neo4j 中有 5 百万个节点。密码运行得这么慢。此外,如果我在 WHERE 子句中使用 OR,架构索引将不起作用: match (p:Person) where p.person_birthday = 19800501205000 OR p.person_name = 'Mike Toms' return p 架构索引有很多限制,所以我必须使用 auto索引。