Поиск друзей n-го уровня в 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')