3

这个问题是如何识别所有实现不扩展某些基类的特定接口的类的延续?.

那里接受的答案建议使用:

MATCH 
   (i:Interface {name:'Action'}  )<-[:IMPLEMENTS|EXTENDS*1..10]- (class), 
   (abstractAction:Class {name:'AbstractAction'}) 
   where not (class)-->(abstractAction)   
RETURN class

这很好用,并给出了符合该条件的类列表。

我唯一的问题是:该接口的名称Action(惊讶)模棱两可。绝对类名com.whatever.foo.bar.Action是。但是,当我将查询更改为使用时,{name:'com.whatever.foo.bar.Action'}我得到一个空结果。

然后我尝试{package:'com.whatever.foo.bar' name:'Action'}了,但这不起作用:

查询中的属性名称之一在数据库中不可用,请确保您没有拼错它,或者当您在应用程序中运行此语句时标签可用(缺少的属性名称是:package

有没有办法将搜索结果减少到我真正关心的那个Action 界面?

4

3 回答 3

3

有一个fqn节点属性 - 全限定名。

所以正确的查询是:

MATCH 
   (i:Interface {fqn:'com.whatever.foo.bar.Action'}  )<-[:IMPLEMENTS|EXTENDS*1..10]- (class), 
   (abstractAction:Class {fqn:'com.whatever.foo.bar.AbstractAction'}) 
   where not (class)-->(abstractAction)   
RETURN class

此查询产生一个笛卡尔产品,这意味着它的性能不是很好。

下图显示了我的一个项目的该查询的执行计划: 在此处输入图像描述

这个问题更详细地处理了这个问题:Why does neo4j warn: "This query builds a cartesian product between disconnected patterns"?

由于此查询仅用于分析目的,而不是针对生产系统执行,因此我会忽略该提示。

于 2019-06-19T12:26:19.810 回答
2

假设您要查找所有com.whatever.foo.bar.Action不扩展com.whatever.foo.bar.AbstractAction查询的实现类应该如下所示:

MATCH 
  (class:Type:Class)-[:EXTENDS|IMPLEMENTS*]->(:Type:Interface{fqn:"com.whatever.foo.bar.Action"})
WHERE NOT
  (class)-[:EXTENDS*]->(:Type:Class{fqn:"com.whatever.foo.bar.AbstractAction"})
RETURN
  class

(恕我直言,这是非常自我表达的)

两个提示:

  • 查找 Java 类型应始终使用Type标签的索引 fqn 属性完成,该属性采用完全限定的类名
  • 您应该始终限定关系,即除了(class)-->(abstractAction)EXTENDS(class)-[:EXTENDS*]->(abstractAction)或 IMPLEMENTS 之外,可能有许多类节点的传出关系(例如 DEPENDS_ON、ANNOTATED_BY),所有这些关系都将被查询遍历
于 2019-06-19T17:01:17.010 回答
1

仔细查看“工作”查询的结果图可以得出简单的答案,因为可以简单地使用该fileName属性:

MATCH 
 (i:Interface {name:"Action", fileName:"/com/whatever/foo/bar/Action.class"}  )<-[:IMPLEMENTS]- (c) 
RETURN c
于 2019-06-19T12:24:16.383 回答