过滤

这是 GraphQL Library 7 版本的文档。对于长期支持 (LTS) 版本 5,请参考 GraphQL Library 5 LTS 版本

您可以在查询或聚合数据时应用过滤器,也可以将过滤规则用于 授权

查询数据时,查询或修改(mutation)的 where 参数中定义的类型可以使用多种运算符,这使您可以过滤查询结果或指定修改所适用的对象集。

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

所有其他运算符都可以使用布尔运算符 ANDORNOT 进行组合。

运算符

布尔运算符

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

containsendsWith字符串比较,而 some关系过滤器

等值运算符

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

例如:

过滤所有名为 John 的用户
query {
  users(where: { NOT: { 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
  }
}

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

空间类型过滤

空间过滤器适用于 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
    }
  }
}

类型比较

字符串比较

以下比较运算符适用于 StringID 类型

  • startsWith

  • endsWith

  • contains

以下是使用这些运算符的示例

过滤名称以 "J" 开头的用户
query {
  users(where: { name: { startsWith: "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://: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 可用于比较 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
  }
}

该查询返回所有将“Action”(动作片)作为其流派之一的电影。

inincludes 适用于除 Boolean 外的所有类型。

接口过滤

您可以使用 typename 过滤器来过滤接口。有关更多详细信息和示例,请参阅 关系 → 接口

关系过滤

过滤是在相关节点列表上完成的,并基于 Cypher 中可用的 列表谓词 all - all none - none some - any single - single

例如,采用这些类型定义

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 参数中提供了一个聚合键。您可以将其用于关系的 nodeedge 上。

以下是一些如何应用此类过滤的示例

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

带运算符的聚合

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

字段类型 描述 运算符 示例

count

这是 where 聚合内的一个特殊“顶层”键,适用于所有关系。它用于计算父节点连接的关系数量。

nodes, edges

query {
  posts(
    where: { likesConnection: { aggregate: { count: { nodes: { gt: 5 } } } } }
  ) {
    content
  }
}

字符串

这些运算符是根据每个字符串的长度计算的。

averageLength shortestLength longestLength

query {
  posts(
    where: {
      likesConnection: {
        aggregate: { node: { name: { longestLength: { gt: 5 } } } }
      }
    }
  ) {
    content
  }
}

数值

用于 IntFloatBigInt 的情况。

average, min, max, sum

query {
  movies(
    where: {
      actorsConnection: {
        aggregate: { edge: { screenTime: { min: { lt: 10 } } } }
      }
    }
  ) {
    title
  }
}

Temporal (时间类型)

用于 DateTimeLocalDateTimeLocalTimeTimeDuration 的情况。

min, max

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

Duration

描述。

average

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

ID

ID 没有聚合过滤器。

-

-