过滤
这是 GraphQL 库版本 6 的文档。有关长期支持 (LTS) 版本 5,请参阅 GraphQL 库版本 5 LTS. |
查询数据时,可以在查询或变异的 where
参数的类型中使用许多运算符,以过滤查询结果或指定变异应用于的对象集。
所有运算符都可以使用布尔运算符 AND
、OR
和 NOT
结合起来。
运算符
布尔运算符
作为独立运算符,布尔运算符接受一个数组参数,其中包含与 where
参数格式相同的项目。这样,它们可以嵌套起来,形成复杂的布尔表达式。
例如,如果你想匹配所有演员,要么是姓名为“Keanu”,要么是不属于“Pantoliano”家族,并且在“The Matrix”电影中出演,那么你可以这样查询:
query {
actors(where: {
AND: [
{
OR: [
{ name_CONTAINS: "Keanu" },
{ NOT: { name_ENDS_WITH: "Pantoliano" } }
]
},
{
movies_SOME: { title_EQ: "The Matrix" }
}
]}
) {
name
movies {
title
}
}
}
相等运算符
所有类型都可以测试相等或不相等。
例如
query {
users(where: { name_EQ: "John" })
id
name
}
对于不相等,你必须使用 NOT
逻辑运算符。
query {
users(where: { NOT: { name_EQ: "John" }})
id
name
}
对于 |
数值运算符
-
_LT
-
_LTE
-
_GT
-
_GTE
以下是如何使用它们的示例
query {
users(where: {age_LT: 50 }) {
id
name
age
}
}
空间类型以不同的方式使用数值过滤,并且它们还具有其他选项。有关更多信息,请参见 过滤空间类型。
空间类型过滤
Point
和 CartesianPoint
类型都使用 数值运算符,并且有一个额外的 _DISTANCE
筛选器。以下是两种类型中每个筛选器执行的操作的列表
-
_LT
:检查一个点是否距离point
字段指定的点不到distance
字段中的距离(以米为单位)。 -
_LTE
:检查一个点是否距离point
字段指定的点不到或等于distance
字段中的距离(以米为单位)。 -
_DISTANCE
:检查一个点是否距离point
字段指定的点正好是distance
字段中的距离(以米为单位)。 -
_GT
:检查一个点是否距离point
字段指定的点大于distance
字段中的距离(以米为单位)。 -
_GTE
:检查一个点是否距离point
字段指定的点大于或等于distance
字段中的距离(以米为单位)。
对于 Point
类型,所有筛选器都接受以下类型作为参数
input PointDistance {
point: Point!
distance: Float!
}
实际上,你可以构造以下查询,它查找距离 Point
5 公里(5000 米)范围内的所有用户
query CloseByUsers($longitude: Float!, $latitude: Float!) {
users(where: { location_LTE: { point: { longitude: $longitude, latitude: $latitude }, distance: 5000 } }) {
name
location {
longitude
latitude
}
}
}
类似地,对于 CartesianPoint
类型,所有筛选器都接受以下类型作为参数
input CartesianPointDistance {
point: CartesianPoint!
distance: Float!
}
CartesianPoint
的相同查询
query CloseByUsers($x: Float!, $y: Float!) {
users(where: { location_LTE: { point: { x: $x, y: $y }, distance: 5000 } }) {
name
location {
x
y
}
}
}
类型比较
字符串比较
以下区分大小写的比较运算符适用于 String
和 ID
类型
-
_STARTS_WITH
-
_ENDS_WITH
-
_CONTAINS
以下是如何使用它们的示例
query {
users(where: { name_STARTS_WITH: "J" }) {
id
name
}
}
此外,数值运算符可以用于字符串比较。它们默认情况下是禁用的。要启用它们,请在 String
的 filters
功能选项中添加它们
const { Neo4jGraphQL } = require("@neo4j/graphql");
const neo4j = require("neo4j-driver");
const typeDefs = `
type User @node {
name: String
}
`;
const driver = neo4j.driver(
"bolt://localhost:7687",
neo4j.auth.basic("username", "password")
);
const features = {
filters: {
String: {
LT: true,
GT: true,
LTE: true,
GTE: true
}
}
};
const neoSchema = new Neo4jGraphQL({ features, typeDefs, driver });
正则表达式匹配
筛选器 _MATCHES
可用于比较 String
和 ID
类型。它接受正则表达式字符串作为参数,并返回所有匹配项。
请注意,正则表达式匹配筛选器默认情况下是禁用的。这是因为,在未受保护的 API 上,它们可能会被用来对后备 Neo4j 数据库执行 ReDoS 攻击.
如果你想启用正则表达式匹配,请更新 features
配置对象。
对于 String
const features = {
filters: {
String: {
MATCHES: true,
}
}
};
const neoSchema = new Neo4jGraphQL({ features, typeDefs, driver });
对于 ID
const features = {
filters: {
ID: {
MATCHES: true,
}
}
};
const neoSchema = new Neo4jGraphQL({ features, typeDefs, driver });
对于 String
和 ID
const features = {
filters: {
String: {
MATCHES: true,
},
ID: {
MATCHES: true,
}
}
};
const neoSchema = new Neo4jGraphQL({ features, typeDefs, driver });
数组比较
考虑以下类型定义
type Movie @node {
id: ID!
title: String!
genres: [String!]
year: Int!
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}
type Actor @node {
id: ID!
name: String!
movies: [Movie!]! @relationship(type: "ACTED_IN", direction: OUT)
}
_IN
运算符适用于非数组字段,并接受一个数组参数
query {
movies(where: { year_IN: [1999, 2000, 2001] }) {
title
year
}
}
该查询返回所有在 1999 年、2000 年和 2001 年上映的电影。
相反,_INCLUDES
运算符适用于数组字段,并接受一个参数
query {
movies(where: { genres_INCLUDES: "Action" }) {
title
genres
}
}
该查询返回所有包含“动作”作为其类型之一的电影。
_IN
和 _INCLUDES
可用于除 Boolean
之外的所有类型。
接口过滤
你可以使用 typename_IN
筛选器过滤接口。有关更多详细信息和示例,请参阅 类型定义 → 类型 → 接口。
关系过滤
关系过滤取决于关系的类型
-
n..1
:通过在field
上指定筛选器,对相关节点的相等或不相等进行筛选。 -
n..m
: 过滤操作是在相关节点列表上进行的,并且基于 Cypher 中可用的列表谓词。
例如,以下类型定义:
type User @node {
id: ID!
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
type Post @node {
id: ID!
content: String
author: User! @relationship(type: "HAS_POST", direction: IN)
likes: [User!]! @relationship(type: "LIKES", direction: IN)
}
n..1
关系
在类型定义示例中,author
表示 Post
上的 n..1
关系,其中给定的 Post
由一个且仅一个 author
创作。 可用的过滤器是 author
。
例如
query {
posts(where: { author: { id_EQ: "7CF1D9D6-E527-4ACD-9C2A-207AE0F5CB8C" } }) {
content
}
}
query {
posts(where: { NOT: { author: { id_EQ: "7CF1D9D6-E527-4ACD-9C2A-207AE0F5CB8C" } } }) {
content
}
}
n..m
关系
在类型定义示例中,posts
表示 User
上的 n..m
关系,其中给定的 User
可以拥有任意数量的 posts
。
例如
query {
users(where: { posts_ALL: { content_CONTAINS: "neo4j" } }) {
name
}
}
query {
users(where: { posts_NONE: { content_CONTAINS: "cypher" } }) {
name
}
}
query {
users(where: { posts_SOME: { content_CONTAINS: "graphql" } }) {
name
}
}
query {
users(where: { posts_SINGLE: { content_CONTAINS: "graph" } }) {
name
}
}
聚合过滤
Neo4j GraphQL 库在每个关系的 where
参数中提供了一个聚合键。 你可以在关系的 node
和 edge
上使用它。
以下是应用这种过滤的一些示例
-
查找点赞数超过 5 的帖子
模式示例type User @node { name: String } type Post @node { content: String likes: [User!]! @relationship(type: "LIKES", direction: IN) }
查询query { posts(where: { likesAggregate: { count_GT: 5 } }) { content } }
-
查找平均乘客年龄大于或等于 18 岁的航班
模式示例type Passenger @node { name: String age: Int } type Flight @node { code: String passengers: [Passenger!]! @relationship(type: "FLYING_ON", direction: IN) }
查询query { flights(where: { passengersAggregate: { node: { age_AVERAGE_GTE: 18 } } }) { code } }
-
查找演员最短屏幕时间小于 10 分钟的电影
模式示例type Movie @node { title: String actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } type Person @node { name: String } type ActedIn @relationshipProperties { screenTime: Int }
查询query { movies(where: { actorsAggregate: { edge: { screenTime_MIN_LT: 10 } } }) { title } }
使用运算符
聚合过滤也可以使用运算符完成。 它们为指定关系的 node
和 edge
上的每个类型提供了自动生成的过滤器。
字段类型 | 描述 | 运算符 | 示例 |
---|---|---|---|
|
|
|
|
|
这些运算符针对每个字符串的长度进行计算。 |
|
|
|
用于 |
|
|
|
用于 |
|
类型定义
查询
|
|
描述。 |
|
类型定义
查询
|
|
ID 不提供任何聚合过滤器。 |
- |
- |