如何将密码查询中多个节点的数据返回到单个graphql字段?

时间:2018-06-22 03:32:52

标签: neo4j cypher graphql

一段时间以来,我一直在尝试一些变通办法,以便将Neo4j查询的正确结果返回给graphql。

让我们以搜索查询为例:

search: {
    args: {
        term: { type: GraphQLString }
    },
    type: new GraphQLList(NodeType),
    resolve(parentValue, { term }, ctx) {
        let params = { term };
        let query = "MATCH(n:node) WHERE n.name CONTAINS { term } RETURN DISTINCT n.name, LABELS(n), n.userID, ID(n);";
         return session.run(query, params)
             .then( result => {
                 const record = result.records;
                 return record.map(function (data) {
                     return {
                          name: data.get('n.name'),
                          id: data.get('ID(n)').low,
                          userID: data.get('n.userID'),
                          label: data.get('LABELS(n)')[0]
                     }
                 })
            })
     }
}

这将返回所有在其name属性中包含某个字符串值的节点,而不会出现问题。但是,如果您在Neo4j查询中描述更多节点,如何将相同属性返回到单个GraphQL字段?例如,当您添加视线匹配时:

MATCH(n:node) 
WHERE n.name CONTAINS { term } 
OPTIONAL MATCH (n)-[:nodeOf]-(b) 
RETURN DISTINCT n.name, LABELS(n), n.userID, ID(n);

在这里,您需要从两个节点nb返回数据。我试图将路径设置为变量:

OPTIONAL MATCH p=(n)-[:nodeOf]-(b)

但是随后我遇到了无法获取某些数据的问题,例如this question中的长度。

因此,如果您有一个描述两个节点的查询,例如(a)-[r]-(b),那么如何将a.nameb.name都返回到单个GraphQL对象类型的name字段?

这是NodeType的简单版本:

const NodeType = new GraphQLObjectType ({
   name: 'Node',
   fields: () => ({
       id: { type: GraphQLInt },
       userID: { type: GraphQLInt },
       name: { type: GraphQLString},
       label: { type: GraphQLString },
       depth: { type: GraphQLInt },      
   })
});

1 个答案:

答案 0 :(得分:1)

如果我了解您的问题,则可以执行以下操作:

MATCH(n:node) 
WHERE n.name CONTAINS { term } 
OPTIONAL MATCH (n)-[:nodeOf]-(b) 
WITH collect({name : n.name})  + collect({name : b.name}) AS allNodes
UNWIND allNodes AS node
RETURN node

在此查询中,我是collecting a.nameb.name在同一集合(allNodes)中。然后,我使用UNWIND将列表转换回单独的行。

相关问题