过滤

这是 GraphQL 库版本 6 的文档。有关长期支持 (LTS) 版本 5,请参阅 GraphQL 库版本 5 LTS.

查询数据时,可以在查询或变异的 where 参数的类型中使用许多运算符,以过滤查询结果或指定变异应用于的对象集。

运算符可以是独立运算符(参见 布尔运算符),也可以附加到字段名称(例如,字符串比较)。

所有运算符都可以使用布尔运算符 ANDORNOT 结合起来。

运算符

布尔运算符

作为独立运算符,布尔运算符接受一个数组参数,其中包含与 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
        }
    }
}

name_CONTAINSname_ENDS_WITH字符串比较,而 movies_SOME关系筛选.

相等运算符

所有类型都可以测试相等或不相等。

例如

过滤所有名为 John 的用户
query {
  users(where: { name_EQ: "John" })
    id
    name
  }

对于不相等,你必须使用 NOT 逻辑运算符。

过滤所有不名为 John 的用户
query {
  users(where: { NOT: { name_EQ: "John" }})
    id
    name
  }

对于 Boolean 类型,相等运算符是唯一可用的运算符。

数值运算符

这些是适用于数值 (IntFloatBigInt)、时间空间 类型的运算符

  • _LT

  • _LTE

  • _GT

  • _GTE

以下是如何使用它们的示例

过滤年龄小于 50 岁的用户
query {
  users(where: {age_LT: 50 }) {
    id
    name
    age
  }
}

空间类型以不同的方式使用数值过滤,并且它们还具有其他选项。有关更多信息,请参见 过滤空间类型

空间类型过滤

PointCartesianPoint 类型都使用 数值运算符,并且有一个额外的 _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
    }
  }
}

类型比较

字符串比较

以下区分大小写的比较运算符适用于 StringID 类型

  • _STARTS_WITH

  • _ENDS_WITH

  • _CONTAINS

以下是如何使用它们的示例

过滤姓名以“J”开头的用户
query {
  users(where: { name_STARTS_WITH: "J" }) {
    id
    name
  }
}

此外,数值运算符可以用于字符串比较。它们默认情况下是禁用的。要启用它们,请在 Stringfilters 功能选项中添加它们

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 可用于比较 StringID 类型。它接受正则表达式字符串作为参数,并返回所有匹配项。

请注意,正则表达式匹配筛选器默认情况下是禁用的。这是因为,在未受保护的 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 });

对于 StringID

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

例如

查找所有其所有帖子都包含搜索词“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 参数中提供了一个聚合键。 你可以在关系的 nodeedge 上使用它。

以下是应用这种过滤的一些示例

  1. 查找点赞数超过 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
        }
    }
  2. 查找平均乘客年龄大于或等于 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
        }
    }
  3. 查找演员最短屏幕时间小于 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
        }
    }

使用运算符

聚合过滤也可以使用运算符完成。 它们为指定关系的 nodeedge 上的每个类型提供了自动生成的过滤器。

字段类型 描述 运算符 示例

count

where 聚合中的一个特殊的“顶层”键,对所有关系都可用。 它用于计算父节点连接到的关系数量。

count_EQUAL, count_GT, count_GTE, count_LT, count_LTE

query {
    posts(where: { likesAggregate: { count_GT: 5 } }) {
        content
    }
}

字符串

这些运算符针对每个字符串的长度进行计算。

_AVERAGE_LENGTH_EQUAL _AVERAGE_LENGTH_GT _AVERAGE_LENGTH_GTE _AVERAGE_LENGTH_LT _AVERAGE_LENGTH_LTE _SHORTEST_LENGTH_EQUAL _SHORTEST_LENGTH_GT _SHORTEST_LENGTH_GTE _SHORTEST_LENGTH_LT _SHORTEST_LENGTH_LTE _LONGEST_LENGTH_EQUAL _LONGEST_LENGTH_GT _LONGEST_LENGTH_GTE _LONGEST_LENGTH_LT _LONGEST_LENGTH_LTE

query {
    posts(where: { likesAggregate: { node: { name_LONGEST_LENGTH_GT: 5 } } }) {
        content
    }
}

数值

用于 IntFloatBigInt 的情况。

_AVERAGE_EQUAL, _AVERAGE_GT, _AVERAGE_GTE, _AVERAGE_LT, _AVERAGE_LTE, _SUM_EQUAL, _SUM_GT, _SUM_GTE, _SUM_LT, _SUM_LTE, _MIN_EQUAL, _MIN_GT, _MIN_GTE, _MIN_LT, _MIN_LTE, _MAX_EQUAL, _MAX_GT, _MAX_GTE, _MAX_LT, _MAX_LTE

query {
    movies(where: { actorsAggregate: { edge: { screenTime_MIN_LT: 10 } } }) {
        title
    }
}

时间

用于 DateTimeLocalDateTimeLocalTimeTimeDuration 的情况。

_MIN_EQUAL, _MIN_GT, _MIN_GTE, _MIN_LT, _MIN_LTE, _MAX_EQUAL, _MAX_GT, _MAX_GTE, _MAX_LT, _MAX_LTE

类型定义
type Event @node {
    title: String!
    startTime: DateTime!
}
查询
query EventsAggregate {
    users(where: { eventsAggregate: { node: { startTime_GT: "2022-08-14T15:00:00Z" } } }) {
        name
    }
}

Duration

描述。

_AVERAGE_EQUAL, _AVERAGE_GT, _AVERAGE_GTE, _AVERAGE_LT, _AVERAGE_LTE

类型定义
type Event @node {
    title: String!
    duration: Duration!
}
查询
query EventsAggregate {
    users(where: { eventsAggregate: { node: { duration_AVERAGE_LT: "PT2H" } } }) {
        name
    }
}

ID

ID 不提供任何聚合过滤器。

-

-