【问题标题】:Returning Neo4j map projection with WebFlux使用 WebFlux 返回 Neo4j 地图投影
【发布时间】:2021-07-03 11:12:21
【问题描述】:

我有节点 usergame 以及它们之间的一些关系。

我的 REST API 应该返回游戏和 1 个用户之间的所有关系。

我使用的密码查询是:

MATCH  (u:User {id: '1234'} ) -[rel]- (game:Game) return game{.*, relationships: collect(DISTINCT rel)}

在我的 Neo4j 浏览器中,一切正常,我看到了我需要的所有属性。 但是 GetMapping 会返回除关系属性之外的所有内容。

Neo4j 浏览器

   {
      "relationships": [
       {
            "identity": 54,
            "start": 9,
            "end": 8,
            "type": "OWNED",
            "properties": {
               "ownedDate": "2021-07-03"
             }
        },
        {
            "identity": 45,
            "start": 9,
            "end": 8,
            "type": "PLAYED",
            "properties": {
               "times": 5
             }
        }
      ],
      "name": "Blood Rage",
      "state": "ACTIVE",
      "id": "1c152c91-4044-41f0-9208-0c436d6f6480",
      "gameUrl": "https://asmodee.de/blood-rage"
    }

GetMapping 结果(如您所见,关系为空,但当有更多关系时,我有更多空的 JsonObjects

     {
        "game": {
            "relationships": [
                {},
                {}
            ],
            
            "name": "Blood Rage",
            "gameUrl": "https://asmodee.de/blood-rage",
            "state": "ACTIVE",
            "id": "1c152c91-4044-41f0-9208-0c436d6f6480"
        }
    }

GetMapping 是:

    ...
final ReactiveNeo4jClient client;
    ...
    ...
    ...
    
    @GetMapping(value = { "/{id}/games"})
    @RolesAllowed({"user", "admin"})
    Flux<Map<String, Object>> findGamesByUser(@PathVariable String id){
        String query = "MATCH  (uuser:User {id: '" + id + "'} ) -[rel]- (game:Game) return game{.*, relationships: collect(DISTINCT rel)}";
        return client.query(query).fetch().all();
    }

关系属性示例

@RelationshipProperties
@Data
@Builder
public class PlayedGame {
    @Id
    @GeneratedValue
    private Long relationshipId;


    @Property
    int times = 0;

    @TargetNode private GameEntity game;

    public int addPlay(){
        this.times = this.times + 1;
        return this.times;
    }
}

我必须在 GetMapping 中进行哪些更改才能显示关系属性?

谢谢你, 凯文

【问题讨论】:

    标签: neo4j cypher spring-webflux spring-data-neo4j


    【解决方案1】:

    您需要返回实际的节点和关系,否则您会丢失 id-mapping。

    SDN 文档中应该有示例。

    最好有一个小的可重现示例(例如使用默认电影图)。

    不确定您的 SDN 设置中是否有问题,一般而言,对于此类简单的查询,您应该能够只使用存储库而无需手动编写密码查询。

    【讨论】:

    • 我做了一个类似的查询,而且我返回的 FLUX 有一些空节点。 MATCH (m:Movie) -[rel]-(p:Person) with toStringList([ TYPE(rel), COUNT(rel)]) as sli, m as mov return mov, collect(sli) as coll 这将是该查询的电影图形版本。在 Neo4J 浏览器中效果很好,但是当我使用 return client.query(query).fetch().all();
    【解决方案2】:

    迈克尔提供的一般信息是正确的,但您的问题还有更多: 首先,如果您使用Neo4jClient,元域模型将被完全忽略。它不会自动映射任何东西,而是使用驱动程序的类型。 结果,您最终将得到一个(此答案的当前状态)InternalRelationship,它没有任何 getter 方法。 我假设您正在使用 Jackson 序列化应用程序中的结果。这就是为什么您会看到表示关系但内部没有任何内容的对象的原因。

    如果您想为您映射事物,请正确创建域对象并(至少)在查询中使用Neo4jTemplate。 如果您对UserGamePlayedGame 等关系属性建模正确,则a

    neo4jTemplate.findAll("MATCH (u:User)&lt;-[rel]-(g:Game) return u, collect(rel), collect(g)", User.class)

    将正确映射结果。此外,如果这就是你所拥有的,你也可以完全跳过自定义查询并使用

    neo4jTemplate.findAll(User.class)

    neo4jTemplate.findById(useId, User.class)

    【讨论】:

      猜你喜欢
      • 2019-04-15
      • 2012-06-08
      • 2021-09-28
      • 1970-01-01
      • 1970-01-01
      • 2017-07-24
      • 1970-01-01
      • 1970-01-01
      • 2012-07-16
      相关资源
      最近更新 更多