2017-02-14 36 views
0

我正在做兩種不同方式的x操作。但在第二種方法中,匹配查詢的計數是不恰當的,這是不可接受的。請建議我失蹤的地方。Neo4j - 不適當的匹配計數

第一種方式:

profile 
WITH [1234] AS sellers_list, 
[12345] AS buyers_list 

MATCH (buyer:Person) WHERE buyer.person_guid IN buyers_list 
MATCH (seller:Person) WHERE seller.person_guid IN sellers_list 

RETURN count(buyer),size(buyers_list),count(seller),size(sellers_list) 

這個結果: enter image description here

第二種方式

profile 
WITH [1234] AS sellers_list, 
[12345] AS buyers_list 

MATCH (seller_member:Person)-[r:TEAM_MEMBER]-(seller_teammate:Person) 
    WHERE seller_member.person_guid IN sellers_list 

WITH FILTER(x IN COLLECT(seller_teammate.person_guid) WHERE NOT(x in sellers_list)) AS sellerteam, sellers_list, buyers_list 

MATCH (seller_member:Person)-[r:EMPLOYED_BY]->(b:Organization) 
MATCH (b)<-[s:EMPLOYED_BY]-(org_member:Person) 
    WHERE seller_member.person_guid=sellers[0] 

WITH FILTER(x IN COLLECT(org_member.person_guid) WHERE NOT(x IN sellerteam)) AS org_members,sellers_list,sellerteam,buyers_list 

WITH sellers+sellerteam+org_members AS all_org_members,sellers_list,sellerteam,org_members,buyers_list 


MATCH (buyer:Person) WHERE buyer.person_guid IN buyers_list 
MATCH (seller:Person) WHERE seller.person_guid IN all_org_members 

RETURN count(buyer),size(buyers_list),count(seller),size(sellers_list) 

這導致: enter image description here

在第二種方法中,我並沒有改變任何地方buyers_list,我算了算,賣方團隊成員和賣方組織成員就是這樣。但買家人數正在變化。爲什麼?

剖析上面的查詢顯示了這個: enter image description here

看着這張圖片中,無人問津的僅僅是1,但爲什麼計數返回45K。

而且,爲什麼90K DB命中45K節點?任何具體的原因,我怎樣才能減少數據庫點擊這裏。

回答

1

要記住一個重要的事情是,在Neo4j的查詢建立的行和列。當你在不連貫的模式之間進行匹配時,你傾向於在當前行上得到笛卡爾積(你可以在你的查詢計劃中看到)。也就是說,笛卡爾產品不一定是錯誤或不好的。如果沒有笛卡爾產品,那麼真的沒有辦法與您的guid列表中的所有賣家相匹配,而且它只是針對您單行的笛卡爾產品。

如果您的賣家比賽後立即返回的所有值,你會看到每一行都有不同的賣家,但所有其他領域(包括買方)是相同的。

你想獲得不同值的計數,count(distinct buyer),這應該給你的1

對於90K擊中了你的預期買家計數,NodeUniqueIndexSeek需要每個查找2分貝命中,和你對45k值進行了查找,因此數學運算出來了。

編輯

如果你還在懷疑,你可以嘗試在隔離大獨特查找(或者儘可能多的隔離,你可以同時不必首先查找45K的GUID)。

MATCH (p:Person) 
WITH p LIMIT 45000 
WITH COLLECT(p.person_guid) as guids 
// you can always take the above subquery, returning 1, to see the timing of just collecting guids 
MATCH (p:Person) 
WHERE p.person_guid in guids 
RETURN COUNT(p) as count 
+0

有沒有其他辦法可以減少dbhits來優化查詢? –

+0

一個獨特的查找是2分貝命中。減少數據庫命中率的唯一方法是減少查詢數量。也就是說,獨特的查詢往往非常快,通常不是性能問題的根源。你正在做一些非常重的收集操作和組合。有時候這些可能會有問題,我會先看看那些。 – InverseFalcon

+0

我添加了一個建議,用於檢查收集節點屬性的時間以及與來自GUID的節點匹配的時間。順便說一句,有什麼理由你爲什麼使用guids而不是節點本身?物業訪問可能很昂貴,你可以跳過你的匹配從指引到節點。 – InverseFalcon