1

Ich habe eine Klasse Benutzer definiert, wie untenSuche n-ter Ebene Freunde in neo4j.rb in bidirektionaler Beziehung Graph

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 

Ich habe user1 und user2 mit User_id 1 bzw. 2 erstellt.

Und dann suche ich folgende der folgenden mit user1.followings(rel_length: 2). Aber das Ergebnis kommt als user1 selbst heraus, weil sowohl user1 als auch user2 aufeinander folgen.

Ich habe order(:breadth_first) und andere Methoden versucht, die Knoten auszuschließen, die bereits besucht wurden. Ich habe vielleicht nicht genug Forschung gemacht, aber hat jemand eine Idee, wie man das macht?

Antwort

1

Zuerst möchten Sie vielleicht die id_property verwenden. Wenn Sie property für user_id verwenden und constraint: :unique festlegen, haben Sie weiterhin die automatisch generierte uuid-Eigenschaft. Das mag sein, was du willst, aber nur ein Kopf hoch. Hier ist die Dokumentation für id_property:

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

Um Ihre Frage, Ihr Code erzeugt Cypher ähnlich wie diese (I benötigt, um die model_class und rel_class Optionen zu ändern):

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

In einer einzigen MATCH Klausel In Cypher stellt Neo4j sicher, dass die gleiche Beziehung für eine einzelne Pfaddurchquerung nicht mehr als einmal durchlaufen wird. Aber wie du gesagt hast, wenn sie einander folgen, bedeutet das, dass es der anderen Beziehung folgen kann, um zum ursprünglichen Benutzer zurückzukehren. Darin können Sie den ursprünglichen Benutzer von den möglichen Ergebnissen ausschließen müssen:

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

In Ruby dies wäre:

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