UNWIND

UNWIND 子句可以将任何列表转换回单个行。这些列表可以是传入的参数、之前collect的结果或其他列表表达式。

Neo4j 不保证 UNWIND 生成的行顺序。唯一保证特定行顺序的子句是ORDER BY

UNWIND 子句的常见用法

  • 创建不同的列表。

  • 从提供给查询的参数列表创建数据。

UNWIND 子句要求您为内部值指定一个新名称。

展开列表

我们想要将文字列表转换为名为x的行并返回它们。

查询
UNWIND [1, 2, 3, null] AS x
RETURN x, 'val' AS y

原始列表中的每个值(包括null)都作为单个行返回。

表 1. 结果
x y

1

"val"

2

"val"

3

"val"

<null>

"val"

行数:4

创建不同的列表

我们想要使用DISTINCT将重复列表转换为集合。

查询
WITH [1, 1, 2, 2] AS coll
UNWIND coll AS x
WITH DISTINCT x
RETURN collect(x) AS setOfVals

原始列表中的每个值都会被展开并通过DISTINCT传递以创建唯一的集合。

表 2. 结果
setOfVals

[1,2]

行数:1

UNWIND与返回列表的任何表达式一起使用

任何返回列表的表达式都可以与UNWIND一起使用。

查询
WITH
  [1, 2] AS a,
  [3, 4] AS b
UNWIND (a + b) AS x
RETURN x

这两个列表(ab)被连接起来形成一个新列表,然后由UNWIND对其进行操作。

表 3. 结果
x

1

2

3

4

行数:4

UNWIND与列表列表一起使用

多个UNWIND子句可以链接起来展开嵌套的列表元素。

查询
WITH [[1, 2], [3, 4], 5] AS nested
UNWIND nested AS x
UNWIND x AS y
RETURN y

第一个UNWINDx产生三行,每一行都包含原始列表的一个元素(其中两个也是列表);即[1, 2][3, 4]5。然后,第二个UNWIND依次对这些行中的每一行进行操作,为y生成五行。

表 4. 结果
y

1

2

3

4

5

行数:5

UNWIND与空列表一起使用

将空列表与UNWIND一起使用不会产生任何行,无论之前是否存在任何行,或者是否正在投影其他值。

本质上,UNWIND []将行数减少到零,从而导致查询停止执行,不返回任何结果。这在诸如UNWIND v之类的案例中很有价值,其中v是来自之前子句的变量,它可能为空列表也可能不为空——当它为空列表时,这将与没有结果的MATCH的行为相同。

查询
UNWIND [] AS empty
RETURN 'literal_that_is_not_returned'
表 5. 结果

(空结果)

行数:0

为了避免在空列表上无意中使用UNWIND,可以使用CASE将空列表替换为null

WITH [] AS list
UNWIND
  CASE
    WHEN list = [] THEN [null]
    ELSE list
  END AS emptylist
RETURN emptylist

UNWIND与不是列表的表达式一起使用

在不返回列表的表达式上使用UNWIND,将返回与在仅包含该表达式的列表上使用UNWIND相同的结果。例如,UNWIND 5实际上等效于UNWIND[5]。对此的例外情况是当表达式返回null时——这将使行数减少到零,导致它停止执行并且不返回任何结果。

查询
UNWIND null AS x
RETURN x, 'some_literal'
表 6. 结果

(空结果)

行数:0

从列表参数创建节点

从参数列表创建多个节点和关系,而不使用FOREACH

参数
{
  "events" : [ {
    "year" : 2014,
    "id" : 1
  }, {
    "year" : 2014,
    "id" : 2
  } ]
}
查询
UNWIND $events AS event
MERGE (y:Year {year: event.year})
MERGE (y)<-[:IN]-(e:Event {id: event.id})
RETURN e.id AS x ORDER BY x

原始列表中的每个值都会被展开并通过MERGE传递以查找或创建节点和关系。

表 7. 结果
x

1

2

行数:2
创建的节点:3
创建的关系:2
设置的属性:3
添加的标签:3