这让我发疯了,特别是因为它打破了我关于Neo4j工作原理的思维模式。
1.失败:放松(5)
从the manual:
确实:
WITH 5 AS x
UNWIND x AS y
RETURN y
产量:
Neo.ClientError.Statement.SyntaxError: Type mismatch: expected List<T> but was Integer (line 2, column 8 (offset: 20))
"UNWIND x AS y "
^
2.作品:unwind([1,[2,3]])
只是为下一步做准备:
WITH [1, [2,3]] AS x
UNWIND x AS y
RETURN y
吐口水:
╒═════╕
│"y" │
╞═════╡
│1 │
├─────┤
│[2,3]│
└─────┘
请注意,第一行是
1
-不是列表。3.作品:unwind(unwind([1,[2,3]])
惊讶吗
WITH [1, [2,3]] AS x
UNWIND x AS y
UNWIND y AS z
RETURN z
输出:
╒═══╕
│"z"│
╞═══╡
│1 │
├───┤
│2 │
├───┤
│3 │
└───┘
因此Neo可以嵌套嵌套展开中的
1
来使用。4.失败:unwind(unwind([1,2]))
WITH [1, 2] AS x
UNWIND x AS y
UNWIND y AS z
RETURN z
错误:
Neo.ClientError.Statement.SyntaxError: Type mismatch: expected List<T> but was Integer (line 3, column 8 (offset: 40))
"UNWIND y AS z "
^
这怎么可能?
我只是不明白,在懒惰的上下文中,如果某项不是列表,则展开可能会选择性地失败,但是直到(迭代)行中没有一个涉及列表的时间如此长。
换句话说,情况3的
1
为什么可以,但情况4的ojit_code没问题?对于那些感兴趣的人,here's the code for the unwind pipe。没有任何迹象表明魔术是如何发生的。
case class UnwindPipe(source: Pipe, collection: Expression, variable: String)
(val id: Id = Id.INVALID_ID)
extends PipeWithSource(source) with ListSupport {
collection.registerOwningPipe(this)
protected def internalCreateResults(input: Iterator[ExecutionContext], state: QueryState): Iterator[ExecutionContext] = {
if (input.hasNext) new UnwindIterator(input, state) else Iterator.empty
}
private class UnwindIterator(input: Iterator[ExecutionContext], state: QueryState) extends Iterator[ExecutionContext] {
private var context: ExecutionContext = _
private var unwindIterator: Iterator[AnyValue] = _
private var nextItem: ExecutionContext = _
prefetch()
override def hasNext: Boolean = nextItem != null
override def next(): ExecutionContext = {
if (hasNext) {
val ret = nextItem
prefetch()
ret
} else Iterator.empty.next()
}
@tailrec
private def prefetch() {
nextItem = null
if (unwindIterator != null && unwindIterator.hasNext) {
nextItem = executionContextFactory.copyWith(context, variable, unwindIterator.next())
} else {
if (input.hasNext) {
context = input.next()
unwindIterator = makeTraversable(collection(context, state)).iterator.asScala
prefetch()
}
}
}
}
}
最佳答案
如果我阅读了您发布的错误消息
然后我注意到您发布了UnwindPipe
的代码,看来您正在看一棵树,却错过了森林。
所以,让我解释一下我的意思。我认为您正在详细查看UnwindPipe
的代码,而在代码中的任何位置都看不到错误的原因。但是,错误消息指出您有一个SyntaxError
而不是Run time error
。你看到你的问题了吗?
该命令的解析器足够聪明,可以知道您给第一个UNWIND
提供了一个列表,然后又足够聪明,可以知道它的结果不是列表,但是第二个UNWIND
需要一个列表,因此解析器使用错误信息。由于解析输入命令失败,因此从未调用或执行UnwindPipe
的代码。