【问题标题】:Neo4j node property comparison during traversalNeo4j 遍历时的节点属性比较
【发布时间】:2015-11-08 17:09:41
【问题描述】:

我对 Neo4j 完全陌生。我正在测试图形数据库,我有以下简单的图形测试结构:different labeled nodes with properties, which are connected

所有节点都有一个属性,称为访问。它是一个字符串元素列表,例如:

{access: ['http', 'www']}

我正在寻找一种解决方案,在该解决方案中,我从连接的起始节点获取所有节点(无论哪种类型或方向),以及它们在节点访问属性上存在交叉点的关系。我将从给定节点开始,并将访问属性与下一个连接的节点进行比较。然后,获取第二个节点的属性并将此访问属性与连接到它们的节点进行比较。等等。目标应该是所有节点及其连接,其中存在访问属性的交叉点。例如,在图的具体结构上,我们从节点 ENC 2009 开始,应该遍历所有连接的节点,直到到达一个在访问属性上没有交集的节点。对于此示例,应达到以下目标:traversed graph

我尝试了以下密码查询,但在作为起始节点的每个节点上都无法正常工作。

MATCH (n:CONFERENCE_SERIE) WHERE n.full_name =~ 'mex.*'
MATCH p = n-[*]-m WHERE FILTER(x IN n.access WHERE x IN m.access)
RETURN p

是否有解决方案,使用 java 遍历框架或使用 cypher,以达到目标并获取此类图的路径?

提前感谢您的帮助。

【问题讨论】:

  • 您是否正在寻找一条路径,其中 所有 节点至少有一个共同的 access 属性?或者您是否在每个单独的步骤中寻找交叉点,即第一个和最后一个节点不需要交叉点?交叉口的大小重要吗?
  • 我正在寻找每一步的交叉点。例如,特定的会议系列可以访问会议实例和提交的论文,但不能访问撰写论文的作者或期刊。路口的大小无关紧要。访问列表中至少匹配一个元素意味着该节点具有访问权限并且可以添加到路径中。

标签: graph properties neo4j cypher traversal


【解决方案1】:

好的,我找到了一个适合我的解决方案。 @MichaelHunger,感谢您的提示。我希望我的同事处理图表信息也很好。我们明天见。

仅供参考:在 traversalDescription 中,我创建了一个 Evaluator。我从路径中获取最后一个关系,并从开始节点和结束节点获取属性访问。现在我可以比较两个属性之间是否存在交集。如果是这样,我将节点包含在结果中并继续。如果不是,则排除该节点并停止遍历。 它有效,我希望它是一个有效的解决方案。

源代码如下:

        TraversalDescription traversal = db.traversalDescription().depthFirst().evaluator(new Evaluator() {
        @Override
        public Evaluation evaluate(Path path) {
            // TODO Auto-generated method stub
            if (path.length() != 0) {
                String[] startAccess = (String[]) path.lastRelationship().getStartNode().getProperty("access");
                String[] endAccess = (String[]) path.lastRelationship().getEndNode().getProperty("access");

                if (checkInteresection(startAccess, endAccess)) {
                    return Evaluation.INCLUDE_AND_CONTINUE;
                } else {
                    return Evaluation.EXCLUDE_AND_PRUNE;
                }
            }
            return Evaluation.INCLUDE_AND_CONTINUE;
        }

【讨论】:

    【解决方案2】:

    java 遍历框架在这方面会更有效,你可以在关系扩展器中使用当前路径的关系

    http://neo4j.com/docs/stable/tutorial-traversal-java-api.html#_pathexpander_relationshipexpander

    在 cypher 中,您可以执行以下操作:

    MATCH (n:CONFERENCE_SERIE) WHERE n.full_name =~ 'mex.*'
    MATCH p = n-[*]-m 
    WHERE FILTER(idx IN range(0,length(p)-2) 
          WHERE ANY(access IN (rels(p)[idx]).access 
                    WHERE access IN (rels(p)[idx+1]).access))
    RETURN p
    

    即有一个计数器从 0 到 path-len-2 查看路径的每一对 rel 并检查下一个 rel 的访问属性中是否包含至少一个 (ANY) 访问代码。

    【讨论】:

    • 我尝试了您的以下密码示例,但不幸的是它不起作用。对于路径,标量函数 size() 不起作用。我想我必须使用函数长度()而不是 size()。如果我用 length() 替换该函数并运行此查询,我将无法返回。如何使用RelationshipExpander 比较两个节点?是否可以访问连接的节点?
    • 在关系扩展器中,您会得到一个传入的路径,其中包含当前扩展的所有节点和关系。
    猜你喜欢
    • 1970-01-01
    • 2020-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多