APOC函数之路径(path)用法

本章来聊聊APOC里路径查询的用法,如果APOC库还不知道是什么或者不知道怎么安装可以参照文章APOC是啥了解了解!!!不要钱

文章中我们以查询产品光伏组件数据为例子。数据基于以下样本图:

返回结果MaterialsRelationship类型是一个关系实体,定义如下:

@Data@RelationshipEntity(type = "Materials")public class MaterialsRelationship {    @Id    private String uuid;    /**     * 开始节点     */    @StartNode    private ProductEntryNode startNode;    /**     * 结束节点     */    @EndNode    private ProductEntryNode endNode;}

比如要查询光伏组件上游关系类型包含Materials,Manufacture,Technology的路径,已知的是光伏组件的id,那么在dao层可以这么做

@Query(" match path=(p:ProductEntry)-[r:Materials|Manufacture|Technology*1..]->(pp)" +       " where p.productEntryId={productEntryId}" +       " return path")List<MaterialsRelationship> getProductEdgesList(String productEntryId);

这样就返回了光伏组件的上游所有路径和节点。用到了'*1..',表示查询的路径长度是无线大。很明显,这样使用在Neo4j里是不允许的。除非你能保证路径长度不超过6(官方推荐数字)。所以考虑把路径长度通过动态参数传入,像这样:

@Query(" match path=(p:ProductEntry)-[r:Materials|Manufacture|Technology*1..{level}]->(pp)" +       " where p.productEntryId={productEntryId}" +       " return path")List<MaterialsRelationship> getProductEdgesList(String productEntryId, int level);

很遗憾的是,cypher不支持这种传参。那怎么办呢?别着急,只要你能遇到的问题,Neo4j开发团队肯定已经遇到并且给出了解决方案。那就是封装成APOC函数了。具体怎么使用,一起来看看。找到apoc.path.expand的函数。这个函数就是查询节点的路径,具体使用语法看下:

apoc.path.expand(start :: ANY?, relationshipFilter :: STRING?, labelFilter :: STRING?, minLevel :: INTEGER?, maxLevel :: INTEGER?) :: (path :: PATH?)

参数说明:

  • start:开始节点,可以是任意类型;

  • relationshipFilter:关系类型,多个用|分开(STRING)

  • labelFilter:标签过滤(STRING)

  • minLevel:最小路径长度(INTEGER)

  • maxLevel:最大路径长度(INTEGER)

  • path:返回结果路径

  • 从参数里可以看出,maxLevel就是需要的传入参数。可以直接在dao层这样写了:

    @Query("match (p:ProductEntry) where p.productEntryId={productEntryId}" +       " call apoc.path.expand(p,'<Materials|<Manufacture|<Technology','+ProductEntry',1,{level}) yield path" +       " return path")List<MaterialsRelationship> getProductEdgesList(String productEntryId, int level);

    其中'<Materials|<Manufacture|<Technology'里的'<'表示指定的方向,如果查询是双向的可以不用加'<'。+ProductEntry表示上游关系只返回每个节点都有ProductEntry标签的路径。测试一下果然可以。说明路径长度可以通过APOC的函数apoc.path.expand动态传参的。返回结果类似这样:

    (p)-[r:Materials]->(pp:ProductEntry)-[r:Materials]->(ppp:ProductEntry)

    其他参数讲解一下。如果要查询下游数据,方向可以这样指定

    'Materials>|Manufacture>'或者没有方向'Materials|Manufacture':

    @Query("match (p:ProductEntry) where p.productEntryId={productEntryId}" +       " call apoc.path.expand(p,'Materials>|Manufacture>|Technology>','',1,{level}) yield path" +       " return path")List<MaterialsRelationship> getProductEdgesList(String productEntryId, int level);

    还可以使用标签过滤器指定遍历终止条件。如果想在遍历遇到包含Engineering标签的节点时立即终止遍历,这个是包含当前Engineering节点的,则可以使用/Engineering节点过滤器:

    @Query("match (p:ProductEntry) where p.productEntryId={productEntryId}" +       " call apoc.path.expand(p,'Materials>|Manufacture>|Technology>','/Engineering',1,{level}) yield path" +       " return path")List<MaterialsRelationship> getProductEdgesList(String productEntryId, int level);

    还可以使用'<Engineering'表示仅返回带有Engineering标签的节点处终止的路径,并且继续往下查找含有Engineering标签的节点,返回的结果类似这样:

    (p)-[r:Materials]->(pp:Engineering)-[r:Materials]->(ppp:Engineering)

    本篇讲的主要是apoc.path.expand函数的用法,包括解决了如何动态传参最大路径长度level,以及其他参数的说明。其中start还可以是id或者list,这些留给大家自己尝试。这里要说明我们不是为了用APOC而用,而是说在cypher中解决不了这样的问题,想到APOC函数有更好的解决方案。

    - 本期

    为方便看最新内容,记得关注Neo4j权威指南

    ©著作权归作者所有,转载或内容合作请联系作者
    • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
      沈念sama阅读 218,607评论 6 507
    • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
      沈念sama阅读 93,239评论 3 395
    • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
      开封第一讲书人阅读 164,960评论 0 355
    • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
      开封第一讲书人阅读 58,750评论 1 294
    • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
      茶点故事阅读 67,764评论 6 392
    • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
      开封第一讲书人阅读 51,604评论 1 305
    • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
      沈念sama阅读 40,347评论 3 418
    • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
      开封第一讲书人阅读 39,253评论 0 276
    • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
      沈念sama阅读 45,702评论 1 315
    • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
      茶点故事阅读 37,893评论 3 336
    • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
      茶点故事阅读 40,015评论 1 348
    • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
      沈念sama阅读 35,734评论 5 346
    • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
      茶点故事阅读 41,352评论 3 330
    • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
      开封第一讲书人阅读 31,934评论 0 22
    • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
      开封第一讲书人阅读 33,052评论 1 270
    • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
      沈念sama阅读 48,216评论 3 371
    • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
      茶点故事阅读 44,969评论 2 355

    推荐阅读更多精彩内容