过滤
运算符
布尔运算符
作为独立运算符,布尔运算符接受一个数组参数,该参数包含与 where
参数格式相同的项目。这样,它们可以嵌套以形成复杂的布尔表达式。
例如,如果您想匹配所有演员,无论是姓名为“基努”还是不属于“潘托利安诺”家族,他们在“黑客帝国”电影中扮演过角色,您可以这样查询:
query {
actors(where: {
AND: [
{
OR: [
{ name_CONTAINS: "Keanu" },
{ NOT: { name_ENDS_WITH: "Pantoliano" } }
]
},
{
movies_SOME: { title: "The Matrix" }
}
]}
) {
name
movies {
title
}
}
}
等式运算符
所有类型都可以测试相等或不相等。
例如
query {
users(where: {name: "John" })
id
name
}
对于不相等,您必须使用 NOT
逻辑运算符。
query {
users(where: { NOT: {name: "John" }})
id
name
}
对于 |
数值运算符
-
_LT
-
_LTE
-
_GT
-
_GTE
以下是使用方法示例
query {
users(where: {age_LT: 50 }) {
id
name
age
}
}
空间类型对数值过滤的使用方式不同,并且还有一些其他选项。有关更多信息,请参见 过滤空间类型。
空间类型过滤
Point
和 CartesianPoint
类型都使用 数值运算符 并具有一个额外的 _DISTANCE
过滤器。以下是两种类型中每个过滤器执行的操作列表
-
_LT
:检查点是否小于distance
字段中指定的距离(以米为单位)远离point
字段中指定的点。 -
_LTE
:检查点是否小于或等于distance
字段中指定的距离(以米为单位)远离point
字段中指定的点。 -
_DISTANCE
:检查点是否与distance
字段中指定的距离(以米为单位)远离point
字段中指定的点完全相同。 -
_GT
:检查点是否大于distance
字段中指定的距离(以米为单位)远离point
字段中指定的点。 -
_GTE
:检查点是否大于或等于distance
字段中指定的距离(以米为单位)远离point
字段中指定的点。
对于 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 {
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 {
id: ID!
title: String!
genres: [String!]
year: Int!
actors: [Actor!]! @relationship(type: "ACTED_IN", direction: IN)
}
type Actor {
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 {
id: ID!
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
type Post {
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: "7CF1D9D6-E527-4ACD-9C2A-207AE0F5CB8C" } }) {
content
}
}
NOT
由不受欢迎的作者撰写的帖子query {
posts(where: { NOT: { author: { id: "7CF1D9D6-E527-4ACD-9C2A-207AE0F5CB8C" } } }) {
content
}
}
n..m
关系
在类型定义示例中,posts
代表 User
上的 n..m
关系,其中给定的 User
可以拥有任意数量的 posts
。
例如
"neo4j"
query {
users(where: { posts_ALL: { content_CONTAINS: "neo4j" } }) {
name
}
}
"cypher"
query {
users(where: { posts_NONE: { content_CONTAINS: "cypher" } }) {
name
}
}
"graphql"
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 { name: String } type Post { content: String likes: [User!]! @relationship(type: "LIKES", direction: IN) }
查询query { posts(where: { likesAggregate: { count_GT: 5 } }) { content } }
-
查找平均乘客年龄大于或等于18岁的航班
模式示例type Passenger { name: String age: Int } type Flight { code: String passengers: [Passenger!]! @relationship(type: "FLYING_ON", direction: IN) }
查询query { flights(where: { passengersAggregate: { node: { age_AVERAGE_GTE: 18 } } }) { code } }
-
查找演员最短时长少于10分钟的电影
模式示例type Movie { title: String actors: [Person!]! @relationship(type: "ACTED_IN", direction: IN, properties: "ActedIn") } type Person { name: String } type ActedIn @relationshipProperties { screenTime: Int }
查询query { movies(where: { actorsAggregate: { edge: { screenTime_MIN_LT: 10 } } }) { title } }
使用运算符
聚合过滤也可以使用运算符完成。它们提供针对指定关系的node
和edge
上每个类型可用的自动生成过滤器。
字段类型 | 描述 | 运算符 | 示例 |
---|---|---|---|
|
|
|
|
|
这些运算符针对每个字符串的长度进行计算。 |
|
|
|
用于 |
|
|
|
用于 |
|
类型定义
查询
|
|
描述。 |
|
类型定义
查询
|
|
ID不可用聚合过滤器。 |
- |
- |