Neo4j 中 String.equals 或 STARTS WITH 的效率

发布于 2025-01-09 02:09:02 字数 1188 浏览 0 评论 0原文

假设我的应用场景如下:

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
      
    哪种解决方案更好?
  • 在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?

  • In Java, String.equals and String.startsWith have almost same time complexity O(n). So is this still the case in neo4j?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梅窗月明清似水 2025-01-16 02:09:02

根据索引偏好的此链接:

https://neo4j.com/docs/ cypher-manual/current/query-tuning/indexes/#_index_preference

引用:

  • 对于 CONTAINS 和 ENDS,TEXT 索引优先于 BTREE 索引
    和。
  • 在所有其他情况下,BTREE 索引优于 TEXT 索引。

Unqoute:

因此,在您的示例中,我将使用

MATCH (:JOJO{name:"Jonathan"})-[:AncestorOf*]-(:JOJO)-[:Owns]->(sp:StandPower)
return sp

一般情况下,进行字符串匹配将执行 STARTS WITH ,因为前者已经在使用索引。如果您执行查询计划来查看有关如何使用索引的详细信息,那就更好了。

According to this link on index preference:

https://neo4j.com/docs/cypher-manual/current/query-tuning/indexes/#_index_preference

Quote:

  • TEXT indexes are preferred over BTREE indexes for CONTAINS and ENDS
    WITH.
  • BTREE indexes are preferred over TEXT indexes in all other cases.

Unqoute:

Thus, on your example I will go with

MATCH (:JOJO{name:"Jonathan"})-[:AncestorOf*]-(:JOJO)-[:Owns]->(sp:StandPower)
return sp

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文