当前位置: 首页 > 知识库问答 >
问题:

使用Cypher和SDN@Query注释在Neo4J中创建唯一路径

杨超
2023-03-14

我想使用Spring数据Neo4j在Neo4j中建模一个包含公司及其业务关系的图。所以我为公司创建了节点,为业务关系创建了边缘。然而,有一系列不同类型的关系(买方、供应商、制造商等,还有一种通用版本“与之做生意”)。每个关系只有一个属性,即目标公司的源公司的内部ID,例如,买方有每个供应商的内部ID。每一对公司在每个方向上都可以有一种类型的关系。

我建立这种关系的方式是为公司设立一个@NodeEntity,为每个不同的业务关系设立一个@RelationshipEntity。由于所有这些关系都具有相同的属性,因此它们都扩展了泛型类,只需将正确的标签添加到边缘:

@RelationshipEntity(type="DOES_BUSINESS_WITH")
public class BusinessRelation  {
    @GraphId
    private Long id;

    @Fetch
    @StartNode
    private Company from;

    @Fetch
    @EndNode
    private Company to;

    @Indexed
    private String knownAsId;

    // getters and setters omitted

}

@RelationshipEntity(type="SUPPLIER")
public class SupplierRelation extends BusinessRelation {

    public SupplierRelation() {
    }
}

因为我有很多不同的关系,所以我想使用一个存储库接口来处理所有这些关系。

现在,当我建立关系时,我想在(已经存在的)公司之间建立新的关系,或者在必要时修改现有的关系。所以我决定使用像这样的CREATE UniQUE cypher子句:

public interface BusinessRelationRepository extends GraphRepository<BusinessRelation> {
     @Query(value="match (source:Company {orgId:{0}}),(target:Company {orgId:{1}}) create unique (source)-[r:SUPPLIER]->(target) return r", elementClass=SupplierRelation.class)
    SupplierRelation createSupplierMarker(String sourceOrgId, String targetOrgId);
    // ...
}

不幸的是,这引发了一个异常:

org.springframework.dao.DataRetrievalFailureException: No such property, '__type__'.; nested exception is org.neo4j.graphdb.NotFoundException: No such property, '__type__'.
    at org.springframework.data.neo4j.support.Neo4jExceptionTranslator.translateExceptionIfPossible(Neo4jExceptionTranslator.java:66)
    at org.springframework.data.neo4j.support.Neo4jTemplate.translateExceptionIfPossible(Neo4jTemplate.java:448)
    at org.springframework.data.neo4j.support.Neo4jTemplate.doExecute(Neo4jTemplate.java:459)
    at org.springframework.data.neo4j.support.Neo4jTemplate.access$000(Neo4jTemplate.java:87)
    at org.springframework.data.neo4j.support.Neo4jTemplate$2.doInTransaction(Neo4jTemplate.java:471)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.data.neo4j.support.Neo4jTemplate.exec(Neo4jTemplate.java:468)
    at org.springframework.data.neo4j.repository.query.GraphRepositoryQuery.execute(GraphRepositoryQuery.java:82)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:421)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:381)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy65.createSupplierMarker(Unknown Source)

我希望将elementClass属性添加到@Query注释中可以为SDN提供足够的信息,以便将结果映射回所需的SupplierRelation,但事实并非如此。实际上,它没有任何效果。

我可以通过将__type__属性添加到Cypher查询来解决这个问题,但是我的代码对Spring Data Neo4j的内部工作方式的了解比我想要的要多。所以这行得通:

@Query(value="match (source:Company {orgId:{0}}),(target:Company {orgId:{1}}) create unique (source)-[r:SUPPLIER {__type__:\"SupplierRelation\"}]->(target) return r")
SupplierRelation createSupplierMarker(String sourceOrgId, String targetOrgId);

有没有更好的解决方案不需要我在代码中设置_type___)属性?

共有1个答案

赵雪峰
2023-03-14

Volker,你说得对,默认的类型表示策略在这里有点过度训练。

实际上,我们想添加一个关系TRS,它只使用rel类型映射到SDN,但我还没有得到它。

您也可以将您的财产添加为

@Indexed(unique=true) private String knownAsId;

然后构造其中一个关系实体实例并使用

template.save(relation);

这也应该行得通。

 类似资料:
  • 我是Neo4J的新手,我正在尝试为基于时空的高可用性查询建立一个概念证明。 我有一个设置,有2个独立的Neo4J企业服务器和一个运行嵌入式HA Neo4J服务器的Java应用程序。 一切都很容易设置,基本查询也很容易设置和高效。另外,按照预期执行从Neo4J SpatialRepository派生的查询。 我正在努力理解的是如何使用SDN与任何其他where子句组合进行空间查询。作为一个微不足道的

  • 我是Neo4j和Cypher的新手,刚刚导入了两个CSV--一个是地点列表,另一个是人员列表。 每个地方都有多个访问过它的人的peopleIDs,存储为数组中的整数。 类似地,每个人都有多个他们访问过的地方的Placeid,这些地方存储在一个数组中。

  • 我有一个Spring Data Neo4j(3.4.0.RELEASE)实体,它带有一个

  • 我在使用Cypher命令将大量数据导入Neo4j实例时遇到了问题。我试图加载大约253K个用户记录,每个记录都有一个唯一的user_id。我的第一步是在tje标签上添加一个唯一的约束,以确保用户只运行一次 然后,我尝试用定期提交运行加载CSV来拉入这些数据。 此查询失败,因此在设置 如果这个ID在CSV文件中只有大约5000行,我可以理解节点的数量是不正确的。但是有什么技术或命令可以用来成功地导入

  • 我有一个CSV数据集,我试图通过它在数据库中已经存在的两个节点类型(和)之间建立关系。 这是数据库信息- 问题是--无论我尝试哪个密码查询,它们都返回相同的东西--“无更改,无行”。 此查询只返回“no rows”。 我还尝试了该查询的一个变体,其中我没有使用函数,但这并没有什么不同。 为了确保节点存在,我从CSV文件中选择了随机单元格值,并使用子句来确保数据库中存在相应的和节点,并且找到了所有节

  • 我的问题与此非常相似:如何通过在neo4j中导入的csv文件创建唯一的节点和关系?我有一个大约250万行的textfile,其中有两列,每一列都是节点ID: 每一行表示一个关系(即250万个关系):first_column nodeid->follows->second_column nodeid。这个文件中大约有80,000个唯一节点。 null 我的主要问题是我想知道如何使这个过程更快。这是在