过滤器与投影

在学习了如何使用 MATCHRETURN 编写基本 Cypher® 查询之后,您可以添加过滤条件并更改投影,只返回某些字段,同时还可以使用参数。

本页展示了在使用电影数据集时如何得到相应的查询。

MATCH(m:Movie)
WHERE (m.title = "The Matrix" AND m.released < 2000)
RETURN m.title, m.tagline, m.released

此查询返回所有标题为 "The Matrix" 且发行年份早于 2000 的电影。它仅返回 1999 年发行的《The Matrix》电影。

过滤

MATCH 子句添加过滤条件的方式类似于添加 RETURN 子句。

  1. 使用方法 .where

    const movieNode = new Cypher.Node()
    const clause = new Cypher.Match(new Cypher.Pattern(movieNode, { labels: ["Movie"] }))
        .where()
        .return(movieNode);
  2. 然后,添加过滤条件,例如

    m.title = "The Matrix"
    1. 使用函数 Cypher.eq() 向 where 语句添加等号运算符(=)。

          .where(Cypher.eq())
    2. Cypher.eq() 接受两个用于比较的参数。对于第一个参数,添加 movieNode 的属性 title

      movieNode.property("title")
    3. 第二个参数是要比较的值("The Matrix")。使用 new Cypher.Param 将其作为参数传递。

      new Cypher.Param("The Matrix")

      Cypher.Param 将字符串替换为合适的 $param,以避免将值直接注入生成的 Cypher 中。

  3. 此时,您的 MATCH 子句应如下所示

    const clause = new Cypher.Match(new (movieNode, { labels: ["Movie"] }))
        .where(Cypher.eq(movieNode.property("title"), new Cypher.Param("The Matrix")))
        .return(movieNode);
  4. 再次运行脚本(node main.js),会得到如下 Cypher

    MATCH (this0:Movie)
    WHERE this0.title = $param0
    RETURN this0

    它通过匹配参数来过滤 Movie 节点的标题,但输出中缺少该参数本身。要解决此问题,请修改脚本末尾的构建过程。

    const { cypher, params } = match.build();
    console.log(cypher);
    console.log(params);

    执行此脚本会输出以下 Cypher 查询及其参数

    MATCH (this0:Movie)
    WHERE this0.title = $param0
    RETURN this0
    { param0: 'The Matrix' }

AND 过滤

以下示例展示了如何向查询添加 AND 过滤条件

  1. .where 之后使用方法 .and,并传入新的 Cypher.eq 谓词

        .where(Cypher.eq(movieNode.property("title"), new Cypher.Param("The Matrix")))
        .and(Cypher.lt(movieNode.property("released"), new Cypher.Param(2000)))

    该方法接受与 .where 相同的参数,并确保使用 AND 正确连接过滤条件。

    在本例中,函数 Cypher.lt 添加了运算符 <(小于)。与之前一样,比较的是 movieNode 的属性与参数。

  2. 再次运行脚本以获取以下结果

    MATCH (this0:Movie)
    WHERE (this0.title = $param0 AND this0.released < $param1)
    RETURN this0
    { param0: 'The Matrix', param1: 1999 }

    AND 操作会自动添加括号以保证运算优先级。这在处理复杂或嵌套过滤条件时非常重要。更多信息请参见高级过滤

投影

返回完整节点并非必须,但您可以通过在 RETURN 中显式设置投影来实现。例如

RETURN m.title, m.tagline, m.released

要定义这些列,您可以将变量传递给 .return 方法。

.return(movieNode.property("title"), movieNode.property("tagline"), movieNode.property("year"));

返回的 Cypher 包含显式投影

MATCH (this0:Movie)
WHERE (this0.title = $param0 AND this0.released < $param1)
RETURN this0.title, this0.tagline, this0.released

复用变量

到目前为止,查询已过滤并返回 Movie 节点的属性 idtitle。然而,直接依赖属性名称可能会导致维护工作不必要地困难。

为避免此问题,请确保过滤条件和投影均使用相同的属性变量(本例中为 movieNode.)。

const titleProp = movieNode.property("title");
const yearProp = movieNode.property("released");
const taglineProp = movieNode.property("tagline");

const clause = new Cypher.Match(movieNode)
    .where(Cypher.eq(titleProp, new Cypher.Param("The Matrix")))
    .and(Cypher.lt(yearProp, new Cypher.Param(2000)))
    .return(titleProp, taglineProp, yearProp);

这样可以保持查询的不同部分保持同步,并使子句本身更简短。

参数也可以赋给变量并重复使用。当对同一参数进行多个过滤时,这尤其有用。请参见关系与高级过滤中的示例。

结论

您的脚本应如下所示

import Cypher from "@neo4j/cypher-builder";

const movieNode = new Cypher.Node({
    labels: ["Movie"],
});

const titleProp = movieNode.property("title");
const yearProp = movieNode.property("released");
const taglineProp = movieNode.property("tagline");

const clause = new Cypher.Match(new Cypher.Pattern(movieNode, { labels: ["Movie"] }))
    .where(Cypher.eq(titleProp, new Cypher.Param("The Matrix")))
    .and(Cypher.lt(yearProp, new Cypher.Param(2000)))
    .return(titleProp, taglineProp, yearProp);

const { cypher, params } = clause.build();
console.log(cypher);
console.log(params);

它会生成如下查询

MATCH (this0:Movie)
WHERE (this0.title = $param0 AND this0.released < $param1)
RETURN this0.title, this0.tagline, this0.released
{ param0: 'The Matrix', param1: 2000 }

现在您可以向简单查询添加参数。

请参阅关系与高级过滤,了解如何向该查询添加关系以及更高级的过滤条件。

© . This site is unofficial and not affiliated with Neo4j, Inc.