neo4j结合graphql,解读 graphql 接口的查询query逻辑
发布于 作者:苏南大叔 来源:程序如此灵动~
本文继续解读neo4j+graphql的migration例子,主要着力点为对graphql里面内置的各自接口名字功用的解读。解读的媒介还是apollo server的默认界面,主要分为query(查询)和mutation(改变)两个大的范围。

大家好,这里是苏南大叔的程序如此灵动博客,这里记录苏南大叔和计算机代码的故事。本文对neo4j+graphql的接口功用做简要分析。测试环境:@neo4j/graphql@3.12.0,neo4j-driver@5.1.0,apollo-server@3.10.3,neo4j@4.4.10,node@16.14.2。
gql定义
本文基础如下文章内容:
测试代码见这里:
本文以Movie类型为例:
type Movie {
title: String!
averageRating: Float!
@cypher(
statement: """
MATCH (this)-[:HAS_REVIEW]->(r:Review)
RETURN avg(r.rating)
"""
)
reviews: [Review!]! @relationship(type: "HAS_REVIEW", direction: OUT)
}Movie有两个属性,
- 字符串
title。 - 浮点数类型
averageRating,它的值由额外的cql计算获得。 [Review]类型reviews,实际为【HAS_REVIEW类型的关系】。因为关联另外一个Review类型,所以它是个可以再展开的项目。
Review定义如下【仅仅作为逻辑理解用途,并非本文重点】:
type Review {
id: ID! @id
rating: Float!
createdAt: DateTime!
content: String!
author: User! @relationship(type: "AUTHORED", direction: IN)
movie: Movie! @relationship(type: "HAS_REVIEW", direction: IN)
}接口范围query
由于篇幅限制,暂时不考虑mutation(改变)的情况,和Movie有关的query查询接口有:
| 大类 | 接口名称 | 说明 |
|---|---|---|
query | Movies | 查询所有Movie |
query | MoviesAggregate | 查询Movie数量 |
query | MoviesConnection | 分页查询Movie |
每个查询中的Variables部分,包括两个输入项目,
$where,常规的where,就是大家理解的那样。$option,这个就是那些limit/order之类的信息。
而$fields,就是接口结果里面返回的字段值。除了常规的可查询项目title和averageRating外,还有个级联查询的reviews,它扩展出的查询是reviewsAggregate和reviewsConnection。

不同级别的接口对比
| 层级 | 类型 | arguments | Fields | 评价 |
|---|---|---|---|---|
| 第一层 | ReviewsAggregateSelection | where | count,title | 结构简单 |
| 第二层 | MovieReviewsAggregateSelection | where,directed | count,node | 结构复杂 |
第一层ReviewsAggregateSelection执行效果

query ExampleQuery($where: ReviewWhere) {
reviewsAggregate(where: $where) {
content {
longest
}
count
rating {
average
}
}
}{
"where": {
"movie": {
"title_CONTAINS": "大叔"
}
}
}结果输出:
{
"data": {
"reviewsAggregate": {
"content": {
"longest": "非常好看"
},
"count": 4,
"rating": {
"average": 31
}
}
}
}第二层ReviewsAggregateSelection执行效果

operation:
query ExampleQuery($where: MovieWhere, $options: MovieOptions) {
movies(where: $where, options: $options) {
title
averageRating
reviews {
author {
username
}
rating
}
reviewsAggregate {
count
node {
rating {
average
}
content {
longest
}
}
}
}
}Variables:
{
"where": {
"title_CONTAINS": "大叔"
},
"options": {
"limit": 2
}
}结果输出为:
{
"data": {
"movies": [
{
"title": "苏南大叔在北京",
"averageRating": 9,
"reviews": [
{
"author": {
"username": "sunan大叔"
},
"rating": 9
}
],
"reviewsAggregate": {
"count": 1,
"node": {
"rating": {
"average": 9
},
"content": {
"longest": "好看"
}
}
}
},
{
"title": "传奇人物:苏南大叔",
"averageRating": 8,
"reviews": [
{
"author": {
"username": "sunan"
},
"rating": 8
}
],
"reviewsAggregate": {
"count": 1,
"node": {
"rating": {
"average": 8
},
"content": {
"longest": "非常好看"
}
}
}
}
]
}
}结论就是:Aggregate里面输出的是各种统计信息。
两层MoviesConnection分页对比
这里就仅仅做截图对比了,如下图所示:


结论是:两个MoviesConnection也是略有不同的。
结束语
目前的结论是:第一层和第二层,虽然名字相同,但是类型不同。详情也都是略有不同的,具体的待后续文章分析。
Aggregate就是各自统计信息,可以在查询的第二层统计,也可以直接统计。Connection就是分页,可以直接分页,也可以在别的查询结果基础上分页。
更多经验文章,请点击苏南大叔的博客: