过滤
运算符
布尔运算符
作为独立运算符,布尔运算符接受一个数组参数,该参数包含与 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://: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不可用聚合过滤器。 |
- |
- |