当前位置:   article > 正文

APOC函数之路径(path)用法_apoc用法

apoc用法

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

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

图片

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

@Data
@RelationshipEntity(type = "Materials")
public class MaterialsRelationship {
    @Id
    private String uuid;
    /\*\*
     \* 开始节点
     \*/
    @StartNode
    private ProductEntryNode startNode;
    /\*\*
     \* 结束节点
     \*/
    @EndNode
    private ProductEntryNode endNode;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

比如要查询光伏组件上游关系类型包含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
  • 2
  • 3
  • 4

这样就返回了光伏组件的上游所有路径和节点。用到了’*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);
  • 1
  • 2
  • 3
  • 4

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

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

参数说明:

  • 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);
  • 1
  • 2
  • 3
  • 4

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

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

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

'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);
  • 1
  • 2
  • 3
  • 4

还可以使用标签过滤器指定遍历终止条件。如果想在遍历遇到包含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);
  • 1
  • 2
  • 3
  • 4

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

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

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

- 本期完 -

有疑问请点赞哈图片,我会及时回复。由于微信限制了公众号留言功能,有问题你可以直接发公众号聊天,我会在下期文章末尾解答你的问题。

为方便看最新内容,记得关注哦图片图片图片  图片

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/727775
推荐阅读
相关标签
  

闽ICP备14008679号