【翻譯自:https://neo4j.com/developer/kb/why-where-clause-does-not-filter/
】
【由Neo4j APAC授權(quán)編譯發(fā)布】
當(dāng)我們在寫Neo4j Cyper查詢語句時,偶爾會發(fā)現(xiàn) WHERE 子句似乎不起作用時,可能會感到非常沮喪,您可以使用下面這些方法找出問題所在。
1、檢查OPTIONAL MATCH之后的WHERE子句
WHERE 子句不能單獨使用,它們始終與MATCH、WITH或OPTIONAL MATCH配對,并且此配對定義了 WHERE 子句執(zhí)行為 false 時的行為。
對于 WITH …? WHERE 和 MATCH …? WHERE,我們期望 WHERE 子句應(yīng)用于所有結(jié)果行,而當(dāng) WHERE 的值為 false 時則過濾行。
但是,OPTIONAL MATCH …? WHERE其行為有所不同,因為OPTIONAL MATCH不會刪除行。使用OPTIONAL MATCH時,如果給定的模式不匹配,或者其WHERE子句的值為false,則模式中新引入的變量對于給定的行將為null。從不刪除行,并且現(xiàn)有變量保持不變,當(dāng)真正的問題是將WHERE子句應(yīng)用于錯誤的事務(wù)時,我們會覺得 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,因此將返回所有電影,沒有電影被過濾掉,但是動畫師集合將僅填充1999年之后發(fā)行的電影。
要解決這個問題,我們需要將WHERE移動到其他位置,以便將其與MATCH或WITH關(guān)聯(lián),以便根據(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
2、WHERE子句中檢查拼寫錯誤或大小寫不匹配
WHERE子句中錯字和拼寫錯誤很容易拋出,包括不匹配。
節(jié)點標(biāo)簽、關(guān)系類型、變量以及屬性鍵和值都區(qū)分大小寫,因此請確保前后一致并正確無誤。
MATCH (m:Movie)
WHERE NOT (m)<-[:worked_on]-(a:animator) AND m.ReleaseYear > 1999
RETURN m
上面的查詢沒有任何拼寫錯誤,但是關(guān)系類型、節(jié)點標(biāo)簽和屬性鍵的大小寫與圖中的實際情況有所不同。
3、檢查應(yīng)為數(shù)值的屬性是否存為字符串
在數(shù)值比較或匹配失敗的情況下,要確保比較的屬性是否為數(shù)值。
在文本結(jié)果視圖中,字符串值將用引號引起來,而數(shù)值將沒有。
在導(dǎo)入過程中,尤其是在CSV導(dǎo)入過程中,請?zhí)貏e注意,因為所有值都被解釋為字符串。您需要使用 toInteger() 或 toFloat() 將字符串轉(zhuǎn)換為數(shù)值,以避免出現(xiàn)此問題。
4、檢查屬性鍵和值中是否存在空格
屬性存在空格會使 WHERE 子句看起來不起作用,通常是圖數(shù)據(jù)而不是查詢本身的問題。
MATCH (m:Movie)<-[:ACTED_IN]-(p:Person)
WHERE p.name = 'Keanu Reeves'
RETURN m
上面的查詢看起來不錯,并且可能是完全正確的。但是,如果節(jié)點的 name 屬性存在空格“ Keanu Reeves”,則該查詢將不起作用。
仔細(xì)檢查節(jié)點和關(guān)系上的預(yù)期字符串值以查看是否存在意外的空格,如果使用Neo4j 瀏覽器,則文本結(jié)果視圖通常是輕松檢測多余空格的最佳方法。使用STARTS WITH、ENDS WITH或CONTAINS進(jìn)行查詢,可以幫助測試屬性值。
屬性鍵中多余的空格很少,但是偶爾會發(fā)生,例如從格式錯誤的文件導(dǎo)入數(shù)據(jù)時。
例如,如果我們嘗試導(dǎo)入具有以下標(biāo)頭的csv文件:
“nickName, firstName,lastName ”
firstName前有空格,lastName后面有空格。導(dǎo)入后,屬性鍵本身將包含空格,因此實際的屬性鍵將變?yōu)椤皀ickName”、“ firstName”和“l(fā)astName ”,如果沒有被發(fā)現(xiàn),可能很快會引起混亂。