2017-03-01 35 views
1

我有一個Neo4j數據庫,包含用戶,內容和主題節點。我想計算給定用戶對特定主題消耗的內容的比例。在密碼查詢中的獨立匹配

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))) 

有兩兩件事讓我最真的在這裏醜:

  • 首先,是COUNT(DISTINCT())一個黑客以避開一個事實,即這兩個MATCH查詢交叉聯接?
  • 浮法師很醜。

第二個是我可以住的東西,但第一個似乎效率低下;有沒有更好的方式來表達這個想法?

回答

1

內容的計數應返回用戶所消費內容的數量,除非他們不止一次使用相同的內容。

而不是匹配主題中的所有內容,如果您的模型允許,您可以只獲得出站CONTAINS關係的大小。

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 

你原來的查詢將返回用戶的內容話題數量的笛卡爾積X主題的內容匹配的數量相匹配。作爲上述的替代方案,您可以重新編寫原始查詢,如下所示。這會獲取用戶爲該主題使用的內容,執行聚合,然後將該主題和結果計數傳遞給查詢中的下一個子句。這會奏效,但是,使用size((t)-[:CONTAINS]->())會更有效率。

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) 
+0

啊,對不起,這是我錯過的細節 - 如果他們在不同的時間使用它們,它們的確可以有多個消費鏈接。對不起,將修改帖子! – Tom

+0

那麼你想清楚地數出它們 - 對嗎?否則你可能會陷入他們超過100%的情況。 –

+0

正確,是的 - 從最簡單的術語來說,我需要一個查詢來說「讓我看看這個內容已被消費的比例」 – Tom