2016-04-08 13 views
1

Meine Datenbank enthält Hotels, Bewertungen von Hotels, Begriffe (z. B. Wörter) in Bewertungen und Themen (z. B. könnte ein Thema sprechen "Mitarbeiter" mit Begriffen beschreiben das Hotelpersonal) als Knoten. Indizes auf allen Knoten sind vorhanden. Beziehungen wie folgt: Hotel < --Review -> Term -> ThemaUmgang mit langen Pfadmuster in neo4j

Ich bin derzeit auf der Suche nach einer effizienten Möglichkeit der Abfrage von Themen, die Pfade zu zwei oder mehr bestimmten Hotels haben. Mit anderen Worten, ich interessiere mich für die gemeinsamen Themen von zwei Hotels. Wenn das Hotel A Pfade zu den Themen 1,2,3 und das Hotel B Pfade zu den Themen 2,3,4 hat, dann sollte das Ergebnis 2,3 sein.

Ich habe versucht, das Folgende unten, aber das scheint sehr ineffizient, was sehr wahrscheinlich ist aufgrund der Anzahl der möglichen Wege zwischen Hotels und Themen. Grundsätzlich könnte jedes Wort in einem Review einen neuen Pfad erzeugen, der überprüft werden muss.

// show all topics that two hotels have in common 
MATCH (h2:Hotel)<--(r2:Review)-->(t2:Term)-->(to:Topic)<--(t1:Term)<--(r1:Review)-->(h1:Hotel) 
WHERE h1.id IN ["id1","id2"] AND h2.id IN ["id1","id2"] AND NOT h1.id=h2.id 
RETURN h1.id,to.topic, count(to) AS topic_mentions 

Ich frage mich, ob es ein schnellerer Weg ist, damit umzugehen, wenn ich das in Java oder ähnlichen Sprache zu implementieren wäre, würde ich wahrscheinlich einen BFS versuchen zu tun in jedem Hotel beginnen und dann nehme die Überlappung von dem, was Ich finde. Ich bin ziemlich sicher, dass das Hinzufügen der transitiven Kanten als direkte Kanten Hotel -> Topic dies beschleunigen würde, aber mein begrenztes Datenbankdesignwissen sagte mir, dass dies unnötig überflüssig und keine gute Praxis sein könnte?

Ich habe versucht, den ID-Abgleich vor dem Mustervergleich mit einer anderen MATCH- und WITH-Klausel durchzuführen, aber dies hat nichts beschleunigt; Ich denke, das Problem liegt wirklich in dem Muster, das sich selbst anpasst.

Antwort

1

Ich habe etwas ähnliches für die Suche KBs erstellt, und eine direkte Beziehung zwischen Hotels und Themen wird diese Suche leicht machen, und es wird schneller. Zum Beispiel Ihre Suche für alle Themen mit mehr als ein Hotel gemeinsam, dann würden Sie verwenden:

MATCH (h1:Hotel)-[:TOPIC]->(t:Topic) 
MATCH (h2:Hotel)-[:TOPIC]->(t:Topic) 
WHERE h1 <> h2 
RETURN h1.id, h2.id, t.topic, count(t) AS topic_mentions 

Beachten Sie, dass dies eine Zählung aller Themen zurückkehren diese beiden Hotels gemeinsam haben, die gegebenen vielleicht nicht was du willst.

Ich bin ziemlich sicher, dass als direkte Kanten Hotel der transitiven Kanten hinzugefügt - dieses Thema beschleunigen würde, aber mein begrenztes Datenbank-Design Wissen hat mir gesagt, dass dies unnötig überflüssig sein könnte und keine gute Praxis?

Alles, was tun würde, ist eine explizite implizite Beziehung zu machen, die eine der Dinge ist, die graph db so mächtig macht. Es gibt den Wartungsaspekt, den es zu beachten gilt - nämlich, wenn jemand die Wörter in einer Rezension aktualisiert, dann müssen Sie sicherstellen, dass die (Hotel-) - [: THEMA] -> (Thema) Beziehungen immer noch gültig sind - aber Sie würden Das musst du sowieso in deinem ursprünglichen Design machen, also keinen Verlust.