无法通过Sping Boot 中的Neo4j实现CRUD操作

kb5ga3dv  于 2022-11-05  发布在  其他
关注(0)|答案(2)|浏览(136)

我在Sping Boot 中通过Neo4j查询实现CRUD操作时遇到了问题。
我的问题位于城市存储库路线存储库最短路径存储库路线实体。
1)当我调用CityRepositorylistAllgetById方法时,我得到了空城市名称,并在添加了如下所示的路线后列出了它的路线。

[
    {
        "id": "077d1b16-9a4b-4fb0-947b-52031774d949",
        "name": "London",
        "routes": []
    },
    {
        "id": "077d1b16-9a4b-4fb0-947b-52031774d949",
        "name": null,
        "routes": [
            {
                "id": "6db5dd3f-085a-4d50-b025-4f0bee847fcf",
                "from": "London",
                "destination": "Berlin",
                "departureTime": "9:00",
                "arriveTime": "11:30",
                "duration": 2.5
            }
        ]
    }
]

2)(编辑)添加City的任意一条路线,调用City的listAll后,得到截图中的这个结果。
第一次
下面是我的项目链接:Project
下面是 Postman 请求的集合:Link
以下是与我的问题相关的屏幕截图:Link
如何解决我的问题?
以下是我的实体,如下面所示的城市和路线。

城市

public class City {

    @Id
    @Property
    private UUID id;

    @Property
    private String name;

    @Relationship(type = "ROUTES", direction = Relationship.Direction.OUTGOING)
    private Set<Route> routes = new HashSet<>();

    public City(String name) {
        this.name = name;
    }
}

路线

public class Route {

    @Id
    @Property
    private UUID id;

    @Property
    private String from;

    @Property
    private String destination;

    @Property
    private String departureTime;

    @Property
    private String arriveTime;

    @Property
    private Double duration;
}

这是我的CityRepository,如下所示。

public interface CityRepository extends Neo4jRepository<City,UUID> {

    @Query("MATCH (city:City) OPTIONAL MATCH (city)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route)")
    List<City> listAll();

    @Query("MATCH (city:City {id: $cityId}) OPTIONAL MATCH (city)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route)")
    City getById(UUID cityId);

    @Query("MATCH (city:City {name: $cityName}) RETURN city")
    City getByCityName(String cityName);

    @Query("CREATE (city:City {id: randomUUID(), name: $cityName}) RETURN city")
    City saveCity(String cityName);

    @Query("MATCH (city:City {id: $cityId}) SET city.name = $cityName RETURN city")
    City updateCity(UUID cityId, String cityName);

    @Query("MATCH (city:City {id: $cityId}) DELETE city")
    void deleteCity(UUID cityId);
}

下面显示的是我的RouteRepository

public interface RouteRepository extends Neo4jRepository<Route,UUID> {

    @Query("MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route) RETURN route")
    List<Route> listAllByCityId(UUID cityId);

    @Query("MATCH (route:Route {id: $routeId}) RETURN route")
    Route getById(UUID routeId);

    @Query("CREATE (city:City {id: $cityId})-[:ROUTES]->(route:Route {id: randomUUID(), from: $from, destination: $destination, departureTime: $departureTime," +
            "arriveTime: $arriveTime, duration: $duration}) " +
            "RETURN route")
    Route saveRoute(UUID cityId, String from, String destination, String departureTime,
                    String arriveTime, double duration);

    @Query("MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route {id: $routeId}) " +
            "SET route.from = $from, route.destination = $destination,route.departureTime = $departureTime," +
            "route.arriveTime = $arriveTime, route.duration = $duration RETURN route")
    Route updateRoute(UUID cityId, UUID routeId, String from, String destination,String departureTime,
                      String arriveTime,double duration);

    @Query("MATCH (city:City {id: $cityId})-[r:ROUTES]->(route:Route {id: $routeId}) DELETE r, route")
    void deleteRoute(UUID cityId, UUID routeId);
}
aij0ehis

aij0ehis1#

第三次更新:自定义保存查询存在问题。使用CREATE....,Neo4j将始终创建新实体。创建至少与一个现有节点的新关系的最安全方法是匹配现有节点,然后在MERGE语句中通过命名引用使用它。我更新了我的项目,但基本解决方案如下:

@Query("MATCH (city:City {id: $cityId}) " +
       "MERGE (city)-[:ROUTES]->(route:Route {id: randomUUID(), from: $from, destination: $destination, departureTime: $departureTime," +
            "arriveTime: $arriveTime, duration: $duration}) " +
            "RETURN route")
Route saveRoute(UUID cityId, String from, String destination, String departureTime,
                    String arriveTime, double duration);

第二次更新:好的,我更新了项目,现在开始在控制器级别上进行Web测试。请看一下并调整它,以重现我现在遗漏的错误。
我无法复制1和4,请查看com.springshortpath.app.ApplicationWebTests#listCitiesWithRoutes/com.springshortpath.app.ApplicationWebTests#listRoutesByCity
对于2和3:查询模式要求至少定义一条路线。2如果还想得到没有路线的城市,你就必须选择匹配。
对于5:Spring Data Neo4j的存储库只能将实体定义作为返回类型来处理。如果您想使用Java驱动程序的类型,请使用SDN的Neo4jClient进行交互。SDN文档/ Neo4jClient
更新到已编辑的问题:
删除进路:错误指出必须先移除相关性。正确的查询应该是MATCH (city:City {id: $cityId})-[r:ROUTES]->(route:Route {id: $routeId}) DELETE r, route
对于无法通过城市UUID找到路线的情况:关系的方向是错误的,正确的一条是:MATCH (city:City {id: $cityId})-[:ROUTES]->(route:Route) RETURN route
我无法重现其他问题,但我在您的存储库的一个分支中创建了我所理解的测试用例:https://github.com/meistermeier/SpringBootNeo4jShortestPath
老马回答:一般来说,我看到了id属性与节点的id之间的误解。
1)当我调用saveCity方法时,id值为0的值被添加了。我不知道为什么id被赋给0。
您将您的id定义为内部Neo4j id。

@Id
@GeneratedValue
private Long id;

因此,SDN将在保存时将该值分配给id字段。节点的内部id将通过Cypher查询中的id(node)进行比较/检索。
3)调用getCityById方法时,看不到任何结果
因此,查询MATCH (city:City {id: $cityId}) RETURN city将不查找正确的id字段,而是查找属性id
2)当我调用listAll方法时,所有的值都被列出了(没有Route值,因为我无法添加Route)
如果您仍然在这里引用CityRepository,您将看不到任何Route,因为您没有返回它们。将查询更改为MATCH (city:City)-[r:ROUTES]->(route:Route) RETURN city, collect(r), collect(route)(或添加一个可选子句来获取路由,而不是要求模式),也会将Routes添加到相应的Cities中。
4)当我调用updateCity方法时,我看不到任何结果。
这应该可以按预期工作,但我假设您说 * couldn 't see any result* 是指其他内容。它应该与方法City getByCityName(String cityName)(包括id属性更改)的结果相同。
对于剩下的问题,我打赌这又是node.id属性与id(node)的问题,所以基本上你有(n:City|Route...{id: $id})的每个地方都应该变成(n:City|Route...) WHERE id(n) = $id

67up9zun

67up9zun2#

请在下面找到我的答复。
1)当我调用saveCity方法时,id值为0的值被添加了。我不知道为什么id被赋给0。
我的回复:当你试图添加到数据库的id值从零开始,这是默认的零。当你添加第二个记录,然后id值将是1 ...类似的,当你添加第三个记录,id值将是2,依此类推。
2)当我调用listAll方法时,所有的值都被列出了(没有Route值,因为我无法添加Route)
我的回复:这是默认行为。
1.当我调用getCityById方法时,我看不到任何结果我的回复:您可以使用getById或getId
4)4)当我调用updateCity方法时,我看不到任何结果。
5)当我调用deleteCity方法时,我看到“City is deleted”,但当我调用listAll方法时,我看到该值。当我得到它时,删除方法无法工作。
6)当我调用saveRoute时,它被添加了,但是有一个id问题。当我调用City方法的listAll时,我看不到它的值。
7)当我调用getRouteById方法时,我看不到任何结果
8)当我调用listAll方法时,我看不到任何结果。
9)当我调用updateRoute方法时,我看不到任何结果。
10)当我调用deleteRoute方法时,我看到“Route is deleted”,但当我调用listAll方法时,我看不到任何结果。我不知道它是否被删除。
我的回复:对于4,5,6,7,8,9,我认为你没有提交或保存有关编程。提交操作后,只有结果将被保存或更新。

相关问题