有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当同一节点存在多个关系时,java Neo4jRepository@Query result错误

假设我们使用这个简单的图模型:

@NodeEntity
class Ad {    
    // GraphId and more Ad attributes...

    @Relationship(type = "HAS_ADVERTISER", direction = Relationship.OUTGOING)
    private User advertiser;

    @Relationship(type = "IS_FAVOURITE_TO", direction = Relationship.OUTGOING)
    private Set<User> favourites = new HashSet<>();

    // Getters and setters
 }

编辑:按照其中一位aswer的建议,我尝试将传入的关系添加到用户实体,但问题仍然存在

@NodeEntity
class User {
    // User attributes. No incoming relationships for HAS_ADVERTISER neither IS_FAVOURITE_TO...

   // EDIT: Added incoming relationships to User entity, but the problem still remains. Tried annotating getters/setters, but neither works
   @Relationship(type = "HAS_ADVERTISER", direction = Relationship.INCOMING)
   private Set<Ad> ads = new HashSet<>();

   @Relationship(type = "IS_FAVOURITE_TO", direction = Relationship.INCOMING)
   private Set<Ad> favourites = new HashSet<>();

   @Relationship(direction = Relationship.INCOMING)
   public Set<Ad> getAds() {
       return ads;
   }

   @Relationship(direction = Relationship.INCOMING)
   public void setAds(Set<Ad> ads) {
       this.ads = ads;
   }

   @Relationship(direction = Relationship.INCOMING)
   public Set<Ad> getFavourites() {
       return favourites;
   }

   @Relationship(direction = Relationship.INCOMING)
   public void setFavourites(Set<Ad> favourites) {
       this.favourites = favourites;
   }
}

如果我通过neo4j控制台执行一个密码查询来检索带有广告商和收藏夹信息的广告,它运行得很好:

MATCH (ad:Ad),
(ad)-[has_advertiser:HAS_ADVERTISER]->(advertiser:User),
(ad)-[is_favourite_to: IS_FAVOURITE_TO] -> (favouriteUser:User)
return ad, has_advertiser, advertiser, is_favourite_to, favouriteUser

enter image description here

但是,如果我通过neo4jRepository执行查询:

  • advertiser用户已正确持久化
  • favourites集中有两个用户:广告客户用户总是被添加到该集中,这是不正确的,因为与该用户没有IS_FAVOURITE_TO关系

@Repository
public interface AdRepository extends Neo4jRepository<Ad> {

    @Query("MATCH (ad:Ad)," +
            "(ad)-[has_advertiser:HAS_ADVERTISER]->(advertiser:User)," +
            "(ad)-[is_favourite_to: IS_FAVOURITE_TO] -> (favouriteUser:User)" +
            "return ad, has_advertiser, advertiser, " +
            "is_favourite_to, favouriteUser ")
    List<Ad> findAds();
 }

enter image description here

我可以在查询或图形模型中更改一些内容来避免这种情况吗? 也许是spring-data-neo4j的bug

版本:

<spring-data-neo4j.version>4.2.0.M1</spring-data-neo4j.version>
<neo4j.ogm.version>2.0.5</neo4j.ogm.version>

共 (2) 个答案

  1. # 1 楼答案

    这是因为OGM认为这是一个模棱两可的模型。如果您将传入的关系添加到User,您的问题应该得到解决

    更新:进一步调查后,这确实是一个bug。已打开https://github.com/neo4j/neo4j-ogm/issues/276

    解决方法是在Ad和User中注释所有getter和setter(并确保@Relationship注释同时包含关系类型和方向)

  2. # 2 楼答案

    编辑,因为我完全忽略了错误的原因

    返回Ad节点时,Spring数据不会填充嵌入节点。你需要一个专门的结果。此外,在查询中,您将返回在Ad类中没有映射的has_advertiseris_favourite_to关系。它们完全无关紧要。将查询更改为

    @Query("MATCH (advertiser:User)<-[:HAS_ADVERTISER]-(a:Ad)-[:IS_FAVOURITE_TO]->(favourite:User) 
    RETURN a AS ad, advertiser, collect(DISTINCT favourite) AS favourites")
    public List<AdWithAdvertiserAndFavouritesResult getAdsWithAdvertisersAndFavourites()
    

    然后分别计算结果

    @QueryResult
    public class AdWithAdvertiserAndFavouritesResult {
        private Ad ad;
        private User advertiser;
        private List<User> favourites;
    
        //only getters, no setters
    }
    

    您可能要考虑定义一个额外的属性,用于{{CD1>},它是唯一的,可以作为索引使用,因为查询本身不会缩放和引发重载:您总是匹配整个集合的^ {CD1>}节点。我强烈建议不要这样做