2014-12-07 24 views
0

這是一個初學者的問題的基礎上,Neo4j的在線培訓。 (第二章:使用模式進行過濾)。過濾使用查詢的WHERE,而無需創建一個新的標識

的問題是關於演員查詢誰與吉恩·哈克曼的工作,但當時他還與羅賓·威廉姆斯的工作不是。

他們的解決方案是:

MATCH (gene:Person {name:"Gene Hackman"})-[:ACTED_IN]->(movie), 
     (other)-[:ACTED_IN]->(movie), 
     (robin:Person {name:"Robin Williams"}) 
WHERE NOT (robin)-[:ACTED_IN]->(movie) 
RETURN DISTINCT other; 

,試圖找出原因確實需要一個新的標識符3號線,我想下面的代碼片段,它沒有發揮出來。

MATCH (gene:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(other) 
WHERE gene.name="Gene Hackman" 
    AND other.name <> "Robin Williams" 
RETURN DISTINCT other; 

和:

MATCH (gene:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(other) 
WHERE gene.name="Gene Hackman" 
    AND NOT "Robin Williams" IN other.name 
RETURN DISTINCT other; 

很顯然,我失去了一些東西。 我會很感激任何指針!

回答

3

你的第一次嘗試:

MATCH (gene:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(other) 
WHERE gene.name="Gene Hackman" 
AND other.name <> "Robin Williams" 
RETURN DISTINCT other; 

這將匹配所有的演員金·哈克曼曾與誰沒有羅賓·威廉姆斯的工作,但是這不履行的而不是當他也被工作組件您簡要。爲了做到這一點,您將不得不綁定關係鏈的movie部分。要使用IN你也必須使用WITH作爲Chrisophe給了一個例子:

MATCH (gene:Person{name:"Gene Hackman"})-[:ACTED_IN]->(movie:Movie)<-[:ACTED_IN]-(other) 
WITH movie, COLLECT(other.name) AS costars 
WHERE NOT "Robin Williams" in costars 
RETURN movie, costars 

不幸的是,現在你有演員名字(字符串)的聚合集合通過電影爲你的結果,而不是在不同的組演員(節點)。爲了避免您可以使用WITH攜帶other前進,而不是other.name串/節點問題。然後,您將使用FILTER謂詞而不是WHERE NOT。儘管如此,您仍然有一些工作要做,以回到一組不同的節點。

MATCH (gene:Person{name:"Gene Hackman"})-[:ACTED_IN]->(movie:Movie)<-[:ACTED_IN]-(other) 
WITH movie, COLLECT(other) AS costars 
WHERE NONE(costar IN costars WHERE costar.name = "Robin Williams") 
RETURN movie, costars 

我想問題是,你爲什麼不想綁定'robin'節點?索引命中和綁定變量很便宜,並且允許Neo4J以其工作方式工作,使用未綁定的字符串將導致與每個節點進行多次交互的成本(「你是羅賓威廉姆斯?」)。

+1

感謝John的跟進,您的代碼能夠正常工作並提供正確的結果!我嘗試了練習,並且看看我是否能夠重複使用相同的代碼爲了過濾掉模式,而不是特定的標識符。 – 2014-12-08 18:43:22

1

你給的第二次嘗試幾乎是正確的,你誤用IN操作符。

IN被用來驗證的元素的集合中存在,或這裏的other.name是一個字符串。

下面是一個例子:

MATCH (n:Person) AS persons 
WITH collect(persons.name) as names 
WHERE NOT 'Gene Hackman' IN names 
RETURN names 

你可以用這個嘗試:

MATCH (gene:Person)-[:ACTED_IN]->()<-[:ACTED_IN]-(other) 
WHERE gene.name="Gene Hackman" 
    AND NOT "Robin Williams" = other.name 
RETURN DISTINCT other; 

但是,你現在有一個很長的模式,將在數據庫中查找。具有多個準確的段是更高性能的。在你的用例中,將會有一個全局圖表查找,如果可能的話應該避免。

+0

嗨克里斯托弗,謝謝你的跟進。你提供的代碼不起作用(它和我使用的第一個代碼片段「AND other.name <>」Robin Williams「)相同。另外,你能否解釋一下爲什麼我濫用了IN,如果它幾乎正確的,我該如何修復它並使其正常工作?再次感謝。 – 2014-12-07 20:40:30

+0

你說得對,它相當於第一個片段,但是它在我的機器上工作,我將更新我的答案以使用IN – 2014-12-07 21:09:15

+0

感謝您的回覆,新代碼給出了錯誤信息 – 2014-12-08 18:45:47

相關問題