0

我有一堂课House和一堂课Room。这些类中的每一个都是 aNodeEntity并且保存在单独的存储库中,HouseRepository并且RoomRepository. House包含一个Set<Room>. 我希望能够删除一个Room实例并自动从类Set<Room>内部删除该实例House。由于 Neo4j 是一个图形数据库,我认为我应该能够声明 theHouse和 each之间的关系,Room并且删除一个Room实例会自动处理这个问题。以下两个类代表HouseRoom

@NodeEntity
public class House {

    @GraphId
    private Long id;

    @Indexed(unique=true) String uid;

    @RelatedTo (type="addition", direction=Direction.OUTGOING)
    @Fetch
    private Set<Room> rooms;

    public House(String uid, Set<Room> rooms) {
        this.uid = uid;
        this.rooms = rooms;
    }

    public House() {
        this.uid = //random uid;
    }
}


@NodeEntity
public class Room {

    @GraphId
    private Long id;

    @Indexed(unique=true) String uid;

    public Room(String uid) {
        this.uid = uid;
    }

    public Room() {
        this.uid = //random uid;
    }
}

我在想我应该能够编写一个 Cypher 查询来解决RoomRepository这个问题,但我不确定。我想过这样的事情:

public interface RoomRepository extends BaseRepository<Room>{

    @Query("start room=node({0}) " +
            "match house-[:addition*]->room" +
            "delete room")
        public void deleteRoomAndRemoveRoomFromHouse(String uid);
}

处理这些类型的删除的推荐方法是什么?

4

1 回答 1

1

你的方法应该几乎可以工作。您可能会遇到异常,因为您尝试删除节点而没有先删除其关系。(除非 SDN 魔法为您解决了这个问题,但我认为它不会拦截密码查询。)

正如您的MATCH子句所代表的那样,它将充当过滤器,这意味着与room您的开始子句中的标识符绑定的任何内容仅在您到达该delete子句时才会保留,前提是它具有至少深度 1 的相关关系。如果您的房间作为参数传递没有至少一个传入[:addition]关系,它不再绑定,不会被删除。也许这是故意的,如果是这样,请保留它,但添加(否则替换为)一个匹配子句,该子句绑定所有房间关系并在删除房间之前删除它们。尝试类似的东西

START room=node({0})
MATCH room-[r]-()
DELETE r, room

但我认为无论是存储库还是Neo4jTemplate应该有大量的巫毒来为你处理这种操作。或者,如果您将高级映射与 一起使用AspectJ,您可能会将各种巧克力片烘焙到您的room实体中。我知道有一个NodeEntity#persist(),我认为也有一个NodeEntity#remove()

删除节点后,它将不会显示在Set<Room>您的房间类字段中。(如果您使用简单的映射,您可能必须手动检索它或将其同步到数据库,可能一个Neo4jTemplate#fetch(),传递该Set<Room>字段,将为您执行此操作。)

于 2013-11-11T20:03:11.227 回答