过滤
这是 GraphQL 库版本 7 的文档。有关长期支持 (LTS) 版本 5,请参考 GraphQL 库版本 5 LTS。 |
您可以在查询或聚合数据时应用过滤器,也可以将过滤规则用于授权。
查询数据时,查询或突变的 where
参数中的类型提供了多种运算符,允许您过滤查询结果或指定突变适用的对象集。
所有运算符都可以使用布尔运算符 AND
、OR
和 NOT
进行组合。
运算符
布尔运算符
作为独立运算符,布尔运算符接受一个数组参数,其项的格式与 where
参数相同。这样,它们可以嵌套以形成复杂的布尔表达式。
例如,如果您想匹配所有名字是“Keanu”或者不属于“Pantoliano”家族、并且出演了电影“The Matrix”的演员,您可以这样查询:
query {
actors(
where: {
AND: [
{
OR: [
{ name: { contains: "Keanu" } }
{ NOT: { name: { endsWith: "Pantoliano" } } }
]
}
{ movies: { some: { title: { eq: "The Matrix" } } } }
]
}
) {
name
movies {
title
}
}
}
相等运算符
所有类型都可以测试相等性或非相等性。
例如
query {
users(where: { NOT: { 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) 字段和笛卡尔 (Cartesian) 字段。它们允许您通过精确相等或基于距离标准来过滤空间数据。
对于精确匹配,请使用 eq 运算符
query {
users(
where: {
location: {
eq: { longitude: 9, latitude: 10, height: 11 }
}
}
) {
name
location {
longitude
latitude
}
}
}
对于基于距离的过滤,请将数值运算符与距离运算符结合使用
query CloseByUsers {
users(
where: {
location: {
distance: { lte: 5000, from: { longitude: 9, latitude: 10, height: 11 } }
}
}
) {
name
location {
longitude
latitude
}
}
}
对于笛卡尔点,请使用
query CloseByUsers {
users(
where: {
location: {
distance: { lte: 5000, from: { x: 9, y: 10, z: 11 } }
}
}
) {
name
location {
x
y
z
}
}
}
类型比较
字符串比较
以下比较运算符可用于 String
和 ID
类型
-
startsWith
-
endsWith
-
contains
以下是使用它们的示例
query {
users(where: { name: { startsWith: "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 });
不区分大小写的比较
不区分大小写的过滤器可以通过 CASE_INSENSITIVE
选项启用
const neoSchema = new Neo4jGraphQL({
features: {
filters: {
String: {
CASE_INSENSITIVE: true,
},
},
},
});
这将启用字符串过滤器上的 caseInsensitive
字段
query {
movies(where: { title: { caseInsensitive: { eq: "the matrix" } } }) {
title
}
}
所有字符串过滤器都可以与 caseInsensitive
一起使用。
正则表达式匹配
过滤器 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
}
}
此查询返回所有将“Action”作为其类型之一的电影。
除了 Boolean
类型,in
和 includes
可用于所有类型。
接口过滤
您可以使用 typename
过滤器来过滤接口。有关更多详细信息和示例,请参阅类型定义 → 类型 → 接口。
关系过滤
例如,以这些类型定义为例
type User @node {
id: ID!
name: String
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}
type Post @node {
id: ID!
content: String
likes: [User!]! @relationship(type: "LIKES", direction: IN)
}
在类型定义示例中,posts
表示 User
上的一个关系,其中一个给定的 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
}
}
"graph"
的用户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: { likesConnection: { aggregate: { count: { nodes: { 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: { passengersConnection: { aggregate: { node: { age: { average: { gt: 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: { actorsConnection: { aggregate: { edge: { screenTime: { min: { lt: 10 } } } } } } ) { title } }
使用运算符
聚合过滤也可以通过运算符完成。它们为指定关系的 node
和 edge
上的每种类型提供了自动生成的过滤器。
字段类型 | 描述 | 运算符 | 示例 |
---|---|---|---|
|
|
|
|
|
这些运算符是根据每个字符串的长度计算的。 |
|
|
|
用于 |
|
|
|
用于 |
|
类型定义
查询
|
|
描述。 |
|
类型定义
查询
|
|
ID 没有可用的聚合过滤器。 |
- |
- |