Cypher查询NOT IN语法问题及节点属性赋值需求
Cypher中IN/NOT IN查询及二进制属性标记的正确实现
一、正确的IN和NOT IN语法
Cypher实现SQL风格的IN/NOT IN需适配不同版本:
- Neo4j 3.0及以上版本,直接使用
NOT IN语法即可:MATCH (temp:APP) -->(temp2:EMAIL_DOMAIN) WHERE temp2.Name NOT IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM'] RETURN temp - Neo4j 2.x及更早版本,需用括号包裹IN判断:
MATCH (temp:APP) -->(temp2:EMAIL_DOMAIN) WHERE NOT (temp2.Name IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM']) RETURN temp
二、第一段代码返回空结果的排查方向
你第一段代码返回空,核心是数据匹配问题而非语法:
- 检查
APP与EMAIL_DOMAIN节点间的关系是否存在,若有特定关系类型(如:HAS_EMAIL_DOMAIN),需明确写在关系位置(如-[:HAS_EMAIL_DOMAIN]->),而非用通用的-[]-> - 核对
EMAIL_DOMAIN的Name属性大小写是否与列表一致,比如数据库中存储的是gmail.com,而你用大写GMAIL.COM会导致匹配失败
三、给节点添加二进制属性的实现
要给APP节点添加二进制标记属性(如is_in_predefined_list,1表示在列表内,0表示不在),可结合CASE表达式与SET子句:
全量标记所有关联节点
MATCH (temp:APP) -->(temp2:EMAIL_DOMAIN) WITH temp, temp2.Name IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM'] AS is_match SET temp.is_in_predefined_list = CASE WHEN is_match THEN 1 ELSE 0 END RETURN temp
仅标记不在列表内的节点
MATCH (temp:APP) -->(temp2:EMAIL_DOMAIN) WHERE temp2.Name NOT IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM'] SET temp.is_in_predefined_list = 0 RETURN temp
覆盖所有APP节点(含无关联EMAIL_DOMAIN的节点)
OPTIONAL MATCH (temp:APP) -->(temp2:EMAIL_DOMAIN) WITH temp, COALESCE(temp2.Name IN ['GMAIL.COM', 'YAHOO.COM', 'OUTLOOK.COM', 'ICLOUD.COM', 'LIVE.COM'], FALSE) AS is_match SET temp.is_in_predefined_list = CASE WHEN is_match THEN 1 ELSE 0 END RETURN temp
内容的提问来源于stack exchange,提问作者DScience97C
相关产品推荐
相关产品推荐

