过滤
|
这是 GraphQL Library 7 版本的文档。对于长期支持 (LTS) 版本 5,请参考 GraphQL Library 5 LTS 版本。 |
您可以在查询或聚合数据时应用过滤器,也可以将过滤规则用于 授权。
查询数据时,查询或修改(mutation)的 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
}
}
}
对于 Cartesian 点,使用
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://: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”(动作片)作为其流派之一的电影。
in 和 includes 适用于除 Boolean 外的所有类型。
接口过滤
您可以使用 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 的文章
Schema 示例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 岁的航班
Schema 示例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 分钟的电影
Schema 示例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 没有聚合过滤器。 |
- |
- |