我在图表中有节点,其属性pathway
存储一系列值,范围从
path:ko00030
path:ko00010
.
.
path:koXXXXX
举个例子,(我将以批量导入格式发布:https://github.com/jexp/batch-import/tree/20)
ko:string:koid name definition l:label pathway:string_array pathway.name:string_array
ko:K00001 E1.1.1.1, adh alcohol dehydrogenase [EC:1.1.1.1] ko path:ko00010|path:ko00071|path:ko00350|path:ko00625|path:ko00626|path:ko00641|path:ko00830
后续节点可能具有不同的路径值组合。
如何使用CYPHER查询path:ko00010
pathway
的所有节点
我最接近的是使用针对不同问题提供的解决方案: How to check array property in neo4j?
match (n:ko)--cpd
Where has(n.pathway) and all ( m in n.pathway where m in ["path:ko00010"])
return n,cpd;
但是这里只返回路径与提供的列表完全匹配的节点。
即。如果我在上面的示例中查询path:ko00010
,我将只能检索保持path:ko00010
的节点作为pathway
属性中的唯一元素而不是包含{{1的节点}以及其他path:ko00010
答案 0 :(得分:3)
在您的查询中,谓词ALL
的扩展名是属性数组中的所有值,这意味着您的查询将仅返回pathway
属性数组中的每个值都在文字数组["path:ko00010"]
。如果我理解你正确,你想要相反,你想测试文字数组["path:ko00010"]
中的所有值都在属性数组pathway
中找到。如果这确实是你想要的,你可以只改变他们的位置,那么你的WHERE
子句将是
WHERE HAS(n.pathway) AND ALL (m IN ["path:ko00010"] WHERE m IN n.pathway)
说您的查询仅匹配您要求的数组和属性数组完全相同的情况并不严格正确。您可以在文字数组中拥有多个值,例如["path:ko00010","path:ko00020"]
,并且只要其属性数组中的所有值都可以匹配,其路径数组中只有一个值的节点也会匹配在文字数组中找到。相反,使用我建议的更改的WHERE
过滤器,查询将匹配其路径属性中具有文字数组的所有值的任何节点。
如果你想用匹配的模式过滤所有必须存在的值数组,这很好。但是,在您的示例中,您只使用一个值,对于这些查询,没有理由使用数组和ALL
谓词。你可以简单地做
WHERE HAS(n.pathway) and "path:ko00010" IN n.pathway
如果在某些情况下您希望包含在路径属性数组中找到任何一组值的结果,则只需从ALL
切换到ANY
WHERE HAS(n.pathway) AND ANY (m IN ["path:ko00010","path:ko00020"] WHERE m IN n.pathway)
此外,您可能不需要检查路径属性是否存在,除非您有一些特殊用途,否则您应该没有HAS(n.pathway)
。
一旦你的查询工作正常,请尝试为参数切换文字字符串和数组!
WHERE {value} IN n.pathway
// or
WHERE ALL (m IN {value_array} WHERE m IN n.pathway)
// or
WHERE ANY (m IN {value_array} WHERE m IN n.pathway)