过滤

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

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

查询数据时,查询或突变的 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
    }
  }
}

对于笛卡尔点,请使用

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://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 可用于 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”作为其类型之一的电影。

除了 Boolean 类型,inincludes 可用于所有类型。

接口过滤

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

关系过滤

过滤是根据相关节点列表进行的,并基于 Cypher 中可用的列表谓词 all - 所有 none - some - 任意 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 的帖子

    模式示例
    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 岁的航班

    模式示例
    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 分钟的电影

    模式示例
    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 上的每种类型提供了自动生成的过滤器。

字段类型 描述 运算符 示例

计数

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

nodesedges

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 的情况。

averageminmaxsum

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

时间

用于 DateTimeLocalDateTimeLocalTimeTimeDuration 的情况。

minmax

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

时长

描述。

平均值

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

ID

ID 没有可用的聚合过滤器。

-

-