一段时间以来,我一直在尝试一些变通办法,以便将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);
在这里,您需要从两个节点n
和b
返回数据。我试图将路径设置为变量:
OPTIONAL MATCH p=(n)-[:nodeOf]-(b)
但是随后我遇到了无法获取某些数据的问题,例如this question中的长度。
因此,如果您有一个描述两个节点的查询,例如(a)-[r]-(b)
,那么如何将a.name
和b.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 },
})
});
答案 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.name
和b.name
在同一集合(allNodes
)中。然后,我使用UNWIND将列表转换回单独的行。