Создание отношений в Neo4J с использованием Spring-Data

Я хочу создать отношения в neo4j, где у человека есть список друзей. Я могу сделать это двумя способами, используя spring-data.

а) Создайте класс Person со списком, представляющим друзей, и аннотируйте его с помощью @Relationship.

@NodeEntity(label="Person")
public class Person {

    @GraphId
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    @Relationship(type = "FRIEND_WITH")
    List<Person> friends; 
}

б) Создайте объект Person без какого-либо списка и создайте отношение «FRIEND_WITH» с Cypher, например

@Query "CREATE (a)-[FRIEND_WITH]->(b)"

Каковы преимущества/недостатки обоих подходов?


person Soumya    schedule 01.11.2015    source источник


Ответы (2)


Везде, где это возможно, вы должны управлять сущностями и отношениями в вашей модели предметной области, используя код, а не запросы. Преимущество выполнения этого в коде заключается в том, что ваши объекты предметной области и граф останутся синхронизированными. Базовый компонент Object Graph Mapper, используемый SDN, не понимает, что делают ваши запросы, и поэтому не может внести какие-либо изменения в вашу модель предметной области за вас. Это означает, что каждый раз, когда вы изменяете базу данных с помощью запроса, вам, возможно, потребуется снова перезагружать все ваши объекты.

person Vince    schedule 01.11.2015
comment
Neo4J поддерживает как однонаправленные, так и двунаправленные отношения. Таким образом, нужно быть вооруженным пользовательскими запросами, если вы хотите играть с направлениями, сохраняя фиксированную структуру данных класса java. Мне казалось, что было бы лучше отделить отношения от структуры класса и динамически создавать или удалять их с помощью шифра по мере необходимости. Я просто хочу знать ваше решение о том же. - person Soumya; 02.11.2015
comment
Строго говоря, Neo4j поддерживает двунаправленный обход: отношение всегда определяется направлением, но вы можете проходить его с любого конца. Я не уверен, что вы подразумеваете под «игрой с направлениями», но SDN 4 поддерживает ВХОДЯЩИЕ, ИСХОДЯЩИЕ и НЕНАПРАВЛЕННЫЕ краевые направления. UNDIRECTED полезен, когда у вас есть семантически рефлексивные отношения между двумя узлами - например. (Человек)-[:FRIENDS_WITH]-›(Человек). Здесь вам не важно направление, вы просто хотите убедиться, что два друга взаимно связаны в вашем домене. Для какого варианта использования вы считаете необходимым использовать запросы? - person Vince; 02.11.2015
comment
Предположим, у меня есть человек А, который следит за рядом других людей, например, в социальных сетях. Таким образом, в объекте Person A есть List‹Person›, который содержит список лиц, за которыми он следит. Это исходящие отношения. Чтобы получить людей, за которыми следит A, мне просто нужно пройтись по списку. Теперь некоторые другие люди также могут быть подписаны на A. Итак, чтобы получить всех тех людей, которые подписаны на A, мне нужно написать собственный запрос, потому что предыдущий список даст мне только людей, на которых подписан A. - person Soumya; 02.11.2015

Я добавляю второй ответ, потому что я не могу форматировать код в комментариях, но что-то подобное будет работать из коробки и не требует никаких запросов.

public class Person {

    private Long id;
    private String name;

    @Relationship(type="FOLLOWS", direction = "OUTGOING")
    private Set<Person> followees = new HashSet<>();

    @Relationship(type="FOLLOWS", direction = "INCOMING")
    private Set<Person> followers = new HashSet<>();

    public void follow(Person p) {
        this.followees.add(p);
        p.followers.add(this);
    }

    public void unfollow(Person p) {
        this.followees.remove(p);
        p.followers.remove(this);
    }
}
person Vince    schedule 02.11.2015
comment
Винс, я ценю твою помощь. Не то чтобы я намеренно не соглашаюсь с вами, но я действительно пытаюсь научиться обращаться с Neo4J. Подходя к сути, в приведенном выше случае, всякий раз, когда есть отношение следования, мне нужно обновить два объекта: объект Person, представляющий подписчика, и объект, представляющий подписчика, поскольку для обоих из них будет либо список подписчиков, либо список подписчиков. сдача. Точно так же это произойдет и в случае отписки. Принимая во внимание, что если мы создаем отношения через шифрование, не требуется обновление объектов и поддержка двух списков. - person Soumya; 02.11.2015
comment
Souma, вы задали вопрос о преимуществах и недостатках использования запросов Cypher для мутации графа в контексте SDN 4/OGM, и я ответил, дав точный ответ вместе с причинами этого. Вы тогда задали другой конкретный вопрос в последующих комментариях, на что я дал второй ответ, который также является точным. Я не знаю, чем еще я могу помочь, возможно, чтение документации SDN поможет вам решить, действительно ли использование OGM является тем, что вы хотите сделать. docs.spring.io/spring-data/neo4j/docs /текущая/ссылка/html - person Vince; 02.11.2015