如何筛选出拥有年龄大于5岁父节点的狗图节点?
问题场景
先创建狗节点及父子关系:
INSERT INTO dog (id, age) VALUES ("mr_whaf", 8), ("mrs_whaf", 3), ("whaf_jr", 0), ("whaf_whaf", 1); RELATE [dog:mr_whaf, dog:mrs_whaf]->parent_of->dog:whaf_jr; RELATE dog:mrs_whaf->parent_of->dog:whaf_whaf;
需求:仅筛选出年龄小于2岁且拥有至少一个年龄大于5岁父节点的狗节点,预期结果只返回whaf_jr。
遇到的问题
执行以下查询时,会返回不符合要求的whaf_whaf(其parents为空数组):
SELECT id,age, <-parent_of<-(dog WHERE age > 5).* AS parents FROM dog WHERE age < 2;
返回结果:
[ { age: 0, id: dog:whaf_jr, parents: [ { age: 8, id: dog:mr_whaf } ] }, { age: 1, id: dog:whaf_whaf, parents: [] } ]
尝试用count(parents)或parents.len()过滤时,要么返回空结果,要么报错:
SELECT id,age, <-parent_of<-(dog WHERE age > 5).* AS parents FROM dog WHERE age < 2 AND count(parents) > 0; -- 返回空数组 SELECT id,age, <-parent_of<-(dog WHERE age > 5).* AS parents FROM dog WHERE age < 2 AND parents.len() > 0; -- 报错:'There was a problem running the len() function. no such method found for the none type'
解决思路
问题核心是:当没有匹配的父节点时,parents字段可能为null而非空数组,导致len()报错;count(parents)的统计逻辑也不符合预期。正确做法是在WHERE子句中直接检查是否存在符合条件的父节点关联,而非先投影字段再过滤。
方案1:使用EXISTS关键字验证关联存在性
SELECT id, age, <-parent_of<-(dog WHERE age > 5).* AS parents FROM dog WHERE age < 2 AND EXISTS (<-parent_of<-(dog WHERE age > 5));
方案2:用MATCH语句清晰表达关联逻辑
MATCH $child isa dog, has age $child_age; MATCH $parent isa dog, has age $parent_age; MATCH ($parent)-[parent_of]->($child); WHERE $child_age < 2 AND $parent_age > 5; SELECT $child.id AS id, $child.age AS age, $parent.* AS parents;
两种查询都会精准返回whaf_jr节点,符合预期需求。
内容的提问来源于stack exchange,提问作者Thomas Hügel
相关产品推荐
相关产品推荐

