原文鏈接:https://neo4j.com/developer/kb/why-where-clause-does-not-filter/
在Cypher語句中,當你發(fā)現(xiàn)WHERE沒有起作用時固蚤,可以嘗試下面的幾種方法找到問題所在债鸡。
檢測WHERE條件是否跟在了OPTIONAL MATCH之后
WHERE語句是不能獨立使用的福荸,它必須配合MATCH需了、WITH或者 OPTIONAL MATCH一起使用。
當“WITH...WHERE"或”MATCH...WHERE"這種查詢語句出現(xiàn)時对嚼,WHERE條件會作用到所有結果集上。通常情況我們期望的是绳慎,剔除那些WHERE條件為False的數(shù)據(jù)纵竖。
然而“OPTIONAL MATCH ... WHERE”的情況略有不同,這個查詢并不會剔除數(shù)據(jù)杏愤。當使用OPTIONAL MATCH時靡砌,當匹配不到數(shù)據(jù)或WHERE條件為False時,這個新引入的變量只會被賦值為null珊楼。原來的數(shù)據(jù)并不會剔除通殃,已存在的變量也不會發(fā)生變化,給人的感覺就是WHERE條件沒有起作用厕宗,而事實上呢画舌,是WHERE被應用到了錯誤的地方。
MATCH (m:Movie)
OPTIONAL MATCH (m)<-[:WORKED_ON]-(a:Animator)
WHERE m.releaseYear > 1999 AND a IS NOT NULL
RETURN m, collect(a) as animators
上面的示例請求已慢,看上去好像是想要查詢1999年后發(fā)行的電影和參與這些電影的動畫制作人曲聂,但是這個查詢是錯誤的。WHERE條件僅僅對OPTIONAL MATCH有作用佑惠,所以朋腋,所有電影都會被查詢出來,沒有一個會被過濾掉兢仰。但是動畫制作人數(shù)據(jù)則返回了參與1999年以后發(fā)行的電影的動畫制作人乍丈。
如果要修復這個查詢語句,只需要將WHERE條件放到合適的位置把将,將它放到MATCH或WITH后面即可篩選出想要的數(shù)據(jù)了轻专。
MATCH (m:Movie)
OPTIONAL MATCH (m)<-[:WORKED_ON]-(a:Animator)
WITH m, a
WHERE m.releaseYear > 1999 AND a IS NOT NULL
RETURN m, collect(a) as animators
檢查WHER條件的拼寫錯誤或大小寫
拼寫錯誤很容易造成WHERE條件子句失效,特別是大小寫問題察蹲。
結點的標簽请垛、關系類型、變量洽议、屬性的鍵和值都是大小寫敏感的宗收,所以一定要確保你寫的是正確的。
MATCH (m:Movie)
WHERE NOT (m)<-[:worked_on]-(a:animator) AND m.ReleaseYear > 1999
RETURN m
上面這個查詢語句看上去沒有任何拼寫錯誤亚兄,但事實上混稽,他在關系類型、結點續(xù)簽以及屬性鍵上大小寫都錯了,所以匈勋,這個查詢的WHERE條件是不起作用礼旅。
檢測屬性的變量類型
在使用int或float類型的比較失敗時,你可以先確認一下屬性的值是不是int或float類型洽洁。
確認方法也很簡單:在neo4j瀏覽器的文本結果視圖模式下痘系,字符串的值是有引號的,而int或float類型的值是沒有饿自。 在導入數(shù)據(jù)時要特別小心汰翠,尤其是CSV文件導入,它會把所有值都轉成字符串昭雌。所以复唤,為了避免這個問題,你需要使用toInteger()或toFloat()把字符串轉成int或float類型烛卧。
屬性的鍵或值的首尾空格
屬性的首尾空格有時會造成WHERE條件無效苟穆,這一般是由于圖中的數(shù)據(jù)問題而不是查詢的問題。
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Keanu Reeves'
RETURN m
上面的查詢語句看上去沒啥問題唱星,但事實上,結點的name屬性是“Keanu Reeves ”跟磨,在結尾有一個空格间聊,所以,這個查詢語句是查不到這個結點的抵拘。
通常情況哎榴,只能仔細檢測結點和關系上的字符串值,看是否有空格僵蛛。如果使用Neo4j瀏覽器尚蝌,文本結果視圖可以很容易發(fā)現(xiàn)空格。另外充尉,查詢時使用 STARTS WITH, ENDS WITH, 或 CONTAINS 這幾個函數(shù)也可以幫助你判斷屬性值是否有空格飘言。
屬性的值里存在空格的情況較少,如果有驼侠,一般都是因為從錯誤格式的文件中導入造成的姿鸿。
例如,嘗試導入一下CSV文件的標題行:?
nickName, firstName,lastName
在firstName的開頭一個空格倒源,在lastName的結尾有一個空格苛预。導入時,屬性鍵就會包含首部空格和尾部空格笋熬,因此實際的屬性鍵就變成了“nickName”热某、” firstName”和“l(fā)astName “,如果沒有檢查出來,那么查詢時就會出問題了昔馋。