查询node属性中的数组元素

时间:2014-01-08 15:52:32

标签: neo4j

我在图表中有节点,其属性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

1 个答案:

答案 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)