1

У меня есть класс пользователя, определенный, как показано нижеПоиск друзья п-го уровня в neo4j.rb в двунаправленных отношениях графа

class User 
    include Neo4j::ActiveNode 
    include Neo4j::Timestamps 
    property :user_id, type: Integer, constraint: :unique 
    property :max_friends_count, type: Integer, default: 5 
    validates :user_id, :presence => true 
    has_many :out, :followings, model_class: :GraphUser, rel_class: :GraphRel, unique: true 
    has_many :in, :followers, model_class: :GraphUser, rel_class: :GraphRel, unique: true 
end 

Я создал user1 и user2 с user_id 1 и 2 соответственно.

И затем я не ищу следующее: user1.followings(rel_length: 2). Но результат получается как user1 сам, потому что оба user1 и user2 следуют друг за другом.

Я пробовал order(:breadth_first) и другие методы, чтобы исключить узлы, которые уже были посещены. Возможно, я не сделал достаточно исследований, но кто-нибудь может понять, как это сделать?

ответ

1

Во-первых, вы можете использовать id_property. Если вы используете property для user_id и установите constraint: :unique, у вас все равно будет создано автоматически созданное uuid. Это может быть то, что вы хотите, а просто голова. Вот документация id_property:

https://github.com/neo4jrb/neo4j/wiki/Neo4j-v3-Unique-IDs

На ваш вопрос, ваш код генерирует Cypher похожее на это (мне нужно было изменить model_class и rel_class варианты):

MATCH user15573 
WHERE (ID(user15573) = {ID_user15573}) 
MATCH user15573-[rel1:`FOLLOWS`*2]->(result_followings:`User`) 

в едином MATCH пункте в Cypher Neo4j будет следить за тем, чтобы одно и то же отношение не проходило более одного раза для одного обхода пути. Но, как вы сказали, если они следуют друг за другом, это означает, что он может следовать другим отношениям, чтобы вернуться к первоначальному пользователю. В том, что может вам нужно исключить первоначальный пользователь из возможных результатов:

MATCH user15573 
WHERE (ID(user15573) = {ID_user15573}) 
MATCH user15573-[rel1:`FOLLOWS`*2]->(result_followings:`User`) 
WHERE result_followings <> user15573 

В Ruby это будет:

user1.as(:source).followings(:target, nil, rel_length: 2).where('source <> target')