Neo4j 中 String.equals 或 STARTS WITH 的效率
假设我的应用场景如下:
JOJO家族的每个成员都以其祖先的名字命名。第一代称为乔纳森,因此乔纳森的直系后裔称为乔纳森·约瑟夫和乔纳森·乔尔诺。依此类推,我们有乔纳森·约瑟夫·承太郎、乔纳森·约瑟夫·乔助、乔纳森·约瑟夫·承太郎乔琳。
(Jonathan)-[:AncestorOf]->(JonathanJoseph)
(Jonathan)-[:AncestorOf]->(JonathanGiorno)
(JonathanJoseph)-[:AncestorOf]->(JonathanJosephJotaro)
(JonathanJoseph)-[:AncestorOf]->(JonathanJosephJosuke)
(JonathanJosephJotaro)-[:AncestorOf]->(JonathanJosephJotaroJolyne)
JOJO家族世代传承着黄金精神,因此每个人都拥有一种特殊的能力,叫做‘站立之力’。但是,我们只关心叶节点(没有后代)上 JOJO 的“站立能力”。
(JonathanGiorno)-[:Owns]->(Gold Experience)
(JonathanJosephJosuke)-[:Owns]->(Crazy Diamond)
(JonathanJosephJotaroJolyne)-[:Owns]->(Stone Free)
问题是:
- 我想编写查询来获取某个家族拥有的“stand power”的所有名称。我想到两个解决方案
- 存储所有祖先节点,使用String.equals获取匹配的祖先节点然后跳转到叶子节点
MATCH (:JOJO{name:"Jonathan"})-[:AncestorOf*]-(:JOJO)-[:Owns]->(sp:StandPower) 返回sp
- 不存储任何祖先节点,使用STARTWITH获取匹配的叶子节点
MATCH (j:JOJO)-[:Owns]->(sp:StandPower) 其中 j.name 以“Jonathan”开头 返回sp
- 存储所有祖先节点,使用String.equals获取匹配的祖先节点然后跳转到叶子节点
- 在Java中,String.equals和String.startsWith的时间复杂度几乎相同O(n)。那么neo4j中还是这样吗?
Suppose my application scenario is as follows:
Each member of the JOJO family is named after his ancestors. The first generation is called Jonathan, so Jonathan's direct descendants are called JonathanJoseph and JonathanGiorno. And so on, we get JonathanJosephJotaro, JonathanJosephJosuke, JonathanJosephJotaroJolyne.
(Jonathan)-[:AncestorOf]->(JonathanJoseph)
(Jonathan)-[:AncestorOf]->(JonathanGiorno)
(JonathanJoseph)-[:AncestorOf]->(JonathanJosephJotaro)
(JonathanJoseph)-[:AncestorOf]->(JonathanJosephJosuke)
(JonathanJosephJotaro)-[:AncestorOf]->(JonathanJosephJotaroJolyne)
The JOJO family has inherited the golden spirit from generation to generation, so everyone has a special ability called 'stand power'. However, we only care about the 'stand power' of the JOJO on the leaf node(which do not have descendants).
(JonathanGiorno)-[:Owns]->(Gold Experience)
(JonathanJosephJosuke)-[:Owns]->(Crazy Diamond)
(JonathanJosephJotaroJolyne)-[:Owns]->(Stone Free)
The question is:
- I want to write queries to get all the names of 'stand power' owned by some family. I think of two solutions
- Store all ancestor nodes, use String.equals to get the matched ancestor node and then hop to the leaf nodes
MATCH (:JOJO{name:"Jonathan"})-[:AncestorOf*]-(:JOJO)-[:Owns]->(sp:StandPower) return sp
- Not store any ancestor nodes, use START WITH to get the matched leaf nodes
MATCH (j:JOJO)-[:Owns]->(sp:StandPower) WHERE j.name STARTS WITH "Jonathan" return sp
Which solution is better?
- Store all ancestor nodes, use String.equals to get the matched ancestor node and then hop to the leaf nodes
- In Java, String.equals and String.startsWith have almost same time complexity O(n). So is this still the case in neo4j?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
根据索引偏好的此链接:
引用:
和。
Unqoute:
因此,在您的示例中,我将使用
一般情况下,进行字符串匹配将执行 STARTS WITH ,因为前者已经在使用索引。如果您执行查询计划来查看有关如何使用索引的详细信息,那就更好了。
According to this link on index preference:
Quote:
WITH.
Unqoute:
Thus, on your example I will go with
In general, doing a string match will out perform STARTS WITH since the former is already utilizing the index. Much better if you do a query plan to see the details on how the indices are being used.