/ / Unabhängige Übereinstimmungen in der Chiffrierabfrage - neo4j, cypher

Unabhängige Übereinstimmungen in der Chiffreabfrage - neo4j, cypher

Ich habe eine Neo4j-Datenbank mit User-, Content- und Topic-Knoten. Ich möchte den Anteil des Inhalts berechnen, der von einem bestimmten Benutzer für ein bestimmtes Thema verbraucht wird.

MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
MATCH (c1:Content)<-[:CONTAINS]-(z)
RETURN toFloat(COUNT(DISTINCT(c))) / toFloat(COUNT(DISTINCT(c1)))

Zwei Dinge kommen mir hier wirklich hässlich vor:

  • Erstens ist es COUNT(DISTINCT()) ein Hack um die Tatsache zu umgehen, dass die beiden MATCH Query-Join-Anfragen?
  • Float Division ist hässlich.

Das zweite ist etwas, mit dem ich leben kann, aber das erste scheint ineffizient; Gibt es eine bessere Möglichkeit, diese Idee auszudrücken?

Antworten:

1 für die Antwort № 1

Die Anzahl der Inhalte sollte die Anzahl der Teile eines Inhalts zurückgeben, die ein Benutzer konsumiert hat, es sei denn, sie haben den gleichen Inhalt mehr als einmal konsumiert.

Anstatt den gesamten Inhalt des Themas zu vergleichen, können Sie, wenn Ihr Modell dies zulässt, einfach die Größe des Ausgangs ermitteln CONTAINS Beziehungen.

MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
RETURN toFloat(count(distinct c))/ size((t)-[:CONTAINS]->()) as proportion

Ihre ursprüngliche Abfrage gibt ein kartesisches Produkt zurückder Anzahl der Übereinstimmungen von Benutzer-Inhalt-Thema x Anzahl der Übereinstimmungen von Thema-Inhalt. Als eine Alternative zu dem oben genannten könnten Sie Ihre ursprüngliche Abfrage wie folgt neu schreiben. Dies ruft den Inhalt ab, der von einem Benutzer für das Thema verbraucht wird, führt die Aggregation durch und übergibt dann das Thema und die resultierende Anzahl an die nächste Klausel in der Abfrage. Dies funktioniert jedoch mit size((t)-[:CONTAINS]->()) wird effizienter sein.

MATCH (u:User)-[:CONSUMED]->(c:Content)<-[:CONTAINS]-(t:Topic)
WHERE ID(u) = 11158 AND ID(t) = 19853
WITH t, count(distinct c ) as distinct_content
MATCH (t)-[:CONTAINS]->(c1:Content)
RETURN toFloat(distinct_content) / count(c1)