2017-05-16 2 views
0

Ich habe folgende Chiffre-Abfrage mit mehreren optionalen Spiele zu optimieren, die mehr auf meinem Rechner werden nicht ausgeführt werden kann (Cartesian Produkt):Wie Cypher-Abfrage mit mehreren optionalen MATCH

match (document:Document)-[*..2]-(relateddocument:Document) 
optional match (document)-[:HAS_CATEGORY]->(c:Category)<-[:HAS_CATEGORY]-(relateddocument) 
optional match (document)-[:HAS_KEYWORD]->(k:Keyword)<-[:HAS_KEYWORD]-(relateddocument) 
optional match (document)-[:HAS_AUTHOR]->(a:Author)<-[:HAS_AUTHOR]-(relateddocument) 
with document, relateddocument, collect(c)+collect(k)+collect(a) as similarity 
where id(document) = 85182 return relateddocument, similarity order by similarity desc limit 5 

Könnten Sie bitte geben Sie mir ein Tipp, wie ich diese Abfrage optimieren könnte?

Antwort

1

Wie die anderen Antworten angeben, müssen Sie die WHERE Klausel so nahe wie möglich an die entsprechenden MATCH setzen, um die Anzahl der Zeilen, die von den MATCH erzeugt zu minimieren.

Darüber hinaus können Sie die kartesischen Produkte von allen Back-to-back OPTIONAL MATCH Klauseln verursacht beseitigen COLLECT unter Verwendung der N Zeilen von jedem MATCH-1 Reihe zu konvertieren. (Die letzten WITH wäre kurz vor den RETURN, und so „verschmolzen“ in die RETURN werden könnte.)

Auch Ihre ORDER BY similarity DESC Klausel macht keinen Sinn (und wird wahrscheinlich einen Fehler verursachen), da similarity a Sammlung. Sie wollten wahrscheinlich SIZE(similarity) anstelle von similarity dort verwenden.

Dies sollte schneller sein:

MATCH (document:Document)-[:HAS_CATEGORY|:HAS_KEYWORD|:HAS_AUTHOR*..2]-(relateddocument:Document) 
WHERE ID(document) = 85182 
OPTIONAL MATCH (document)-[:HAS_CATEGORY]->(c:Category)<-[:HAS_CATEGORY]-(relateddocument) 
WITH document, relateddocument, COLLECT(c) AS cs 
OPTIONAL MATCH (document)-[:HAS_KEYWORD]->(k:Keyword)<-[:HAS_KEYWORD]-(relateddocument) 
WITH document, relateddocument, cs, COLLECT(k) AS ks 
OPTIONAL MATCH (document)-[:HAS_AUTHOR]->(a:Author)<-[:HAS_AUTHOR]-(relateddocument) 
RETURN relateddocument, cs+ks+collect(a) as similarity 
ORDER BY SIZE(similarity) DESC 
LIMIT 5; 

Beachten Sie, dass die ersten MATCH[:HAS_CATEGORY|:HAS_KEYWORD|:HAS_AUTHOR*..2] auch verwendet, um die Beziehungstypen zu filtern, im Fall, dass Ihre Dokumente viele Beziehungen zu anderen Arten. Das könnte die Anzahl der Zeilen, die von der ersten MATCH generiert werden, weiter reduzieren, was den Arbeitsaufwand der gesamten Abfrage reduzieren würde.

0

Eine Möglichkeit, es sofort zu verbessern, ist die WHERE-ID (Dokument) = 85182 direkt unter der MATCH-Anweisung zu verschieben. Das sollte einen großen Unterschied machen, wenn Sie die Abfrage PROFILIEREN.

Grüße, Tom

0

Das Hauptproblem ist, dass match (document:Document)-[*..2]-(relateddocument:Document) zwischen allen Dokumenten zu allen Dokumenten 2 Links entfernt, und die WITH zwischen dem Spiel und dem ID-Filter sagen Cypher nicht anzuwenden, um die Filter ein Kartesisches Produkt ist bis NACHDEM es die ganze Arbeit getan hat. Durch Verschieben der WHERE-ID (...) vor die WITH wird Cypher wissen, dass es sicher ist, (Dokument: Dokument) auf nur ID 85182 zu beschränken und somit die n^2 Übereinstimmung von im Grunde allen Dokumenten zu allen Dokumenten zu vermeiden.

MATCH (document:Document)-[*..2]-(relateddocument:Document) 
WHERE id(document) = 85182 
WITH document, relateddocument 
OPTIONAL MATCH (document)-[:HAS_CATEGORY]->(c:Category)<-[:HAS_CATEGORY]-(relateddocument) 
OPTIONAL MATCH (document)-[:HAS_KEYWORD]->(k:Keyword)<-[:HAS_KEYWORD]-(relateddocument) 
OPTIONAL MATCH (document)-[:HAS_AUTHOR]->(a:Author)<-[:HAS_AUTHOR]-(relateddocument) 
WITH relateddocument, collect(c)+collect(k)+collect(a) as similarity 
RETURN relateddocument, similarity 
order by similarity desc 
limit 5 
Verwandte Themen