Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Neo4j 与属性(和标签?)的可选匹配_Neo4j - Fatal编程技术网

Neo4j 与属性(和标签?)的可选匹配

Neo4j 与属性(和标签?)的可选匹配,neo4j,Neo4j,我正在尝试用Neo4j构建这个模型 现在我需要一个查询来确定时间线路径是否已经存在。问题是,我似乎无法使节点成为可选的,同时检查属性是否存在 理想情况下,我希望此查询: START a=node(2) MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day WHERE b.year = 2013 AND c.month = 7 AND d.day = 28 RETURN b, c, d

我正在尝试用Neo4j构建这个模型

现在我需要一个查询来确定时间线路径是否已经存在。问题是,我似乎无法使节点成为可选的,同时检查属性是否存在

理想情况下,我希望此查询:

START a=node(2)
MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(2)
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(*) 
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d 
WHERE b.year? = 2010 AND c.month? = 1 AND d.day? = 1 
RETURN b AS year, c AS month, d AS day
但由于可选节点上的标签似乎不受支持,我将使用以下查询:

START a=node(2)
MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(2)
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(*) 
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d 
WHERE b.year? = 2010 AND c.month? = 1 AND d.day? = 1 
RETURN b AS year, c AS month, d AS day
如果没有WHERE条款,则返回:

a    b    c
null null null
结果很好,因为我知道我必须创建一个年、月和日节点。但是如果没有WHERE子句,我无法指定使整个查询无效的日期

我使用的是Neo4j 2.0.0-M03

更新: 澄清标签不起作用的原因。这是在新数据库上运行的

在控制台中:

neo4j-sh (0)$ CREATE (n:timeline) RETURN n;
==> +-----------+
==> | n         |
==> +-----------+
==> | Node[1]{} |
==> +-----------+
==> 1 row
==> Nodes created: 1
==> Labels added: 1
==> 967 ms
neo4j-sh (0)$ START a=node(1) MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day WHERE b.year = 2013 AND c.month = 7 AND d.day = 28 RETURN b as year, c as month, d as day;
==> Unrecognized option '['
在数据浏览器中:

START a=node(1) MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day WHERE b.year = 2013 AND c.month = 7 AND d.day = 28 RETURN b as year, c as month, d as day;
Returned 0 rows. Query took 138ms
Not found
There is no data matching your query in the database.
我刚刚发现这些查询在我的代码中工作,但在Neo4j控制台或数据浏览器中不起作用。我假设这些查询是“完美的”,因此以前没有在我的代码中测试这些查询。控制台和数据浏览器给出不同的结果也很奇怪。在开始时选择节点(*)而不是节点(1)不会产生任何影响

更新2: 我和彼得·纽鲍尔(Peter Neubauer)发布的例子gists玩了一会儿。问题是,这个示例返回全部或全部不返回。而我想让返回的列成为可选的。因此,在本例中,我希望Query3返回:

Columns: year, month, day
Data: 2010, null, null
但它的回报是:

Query took 264 ms and returned no rows.
当我将属性设置为可选时,如下所示:

START a=node(*) 
MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day 
WHERE b.year? = 2010 AND c.month? = 1 AND d.day? = 1 
RETURN b AS year, c AS month, d AS day
我(在gists网站上)得到:

关键是:这只发生在firefox上,在chrome上返回:查询耗时1毫秒,没有返回任何行

然后这个查询:

START a=node(2)
MATCH a:timeline -[?]-> b:time_year -[?]-> c:time_month -[?]-> d:time_day
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(2)
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d
WHERE b.year = 2013 AND c.month = 7 AND d.day = 28
RETURN b, c, d
START a=node(*) 
MATCH a:timeline -[?]-> b -[?]-> c -[?]-> d 
WHERE b.year? = 2010 AND c.month? = 1 AND d.day? = 1 
RETURN b AS year, c AS month, d AS day
返回:

Columns: year, month, day
Data: (9:time_year {name:"Year 2010", year:2010}), [empty table cell], [empty table cell]
这是我想要的结果(但不使用标签)

然后在Chrome上执行相同的查询:

Query took 4 ms and returned no rows.
到目前为止,我的结论是:
有5种不同的环境可提供不同的结果:

  • 我自己用jadell的php4neoj编写代码
  • 使用数据浏览器的web界面
  • 使用控制台的web界面
  • 使用Firefox的gists网站
  • 使用Chrome的gists网站
我还没有试过:

  • 控制台从批处理文件开始
  • 使用Opera的gists网站
  • 位于的neo4j控制台(我希望它能给出与GIST相同的结果,因为它看起来一样,但我还没有测试过)

因此,我有一系列关于查询和一系列环境的变体。也许可以编写脚本,让查询在不同的环境中运行并返回结果。然后我可以将结果放在一个表中,其中一个轴是环境,另一个轴是正在测试的查询。

从本页获得了答案:


然而,关于标签的附加问题目前仍然是一个谜。

我对此做了一个图表要点,请参阅,标签似乎正在发挥作用。想要做出贡献并澄清吗?

针对每个可选标签约束执行此操作以解决此问题

CASE
    WHEN b IS NOT NULL AND ANY(x IN LABELS(b) WHERE x="time_year") THEN b
    ELSE NULL 
END AS newB
因为b是任何类型的节点,这将确保如果它存在,它是正确的标签。这有点冗长,但是哦,好吧

--编辑-- 根据flip对索引的评论,我做了以下工作:(执行计划基于每次查询的第二次运行)

第一个想法

MATCH a:timeline WITH a
MATCH a-[?]->b 
WITH a, b,  CASE WHEN b IS NOT NULL AND ANY (x IN LABELS(b) 
                                             WHERE x="time_year")  THEN b  ELSE NULL END AS newB 
WHERE newB.year? = 2010 
RETURN a, newB AS year

Detailed Query Results
Query Results

+--------------------------------+
| a         | year               |
+--------------------------------+
| Node[7]{} | Node[8]{year:2010} |
| Node[9]{} |              |
+--------------------------------+
2 rows
2 ms

Execution Plan

ColumnFilter(symKeys=["a", "b", "newB", "year"], returnItemNames=["a", "year"], _rows=2, _db_hits=0)
Extract(symKeys=["a", "b", "newB"], exprKeys=["year"], _rows=2, _db_hits=0)
  Filter(pred="nullable([($anonfun$nullableProperty$3$$anonfun$apply$21$$anon$1,true)],[$anonfun$nullableProperty$3$$anonfun$apply$21$$anon$1 == Literal(2010)])", _rows=2, _db_hits=2)
    ColumnFilter(symKeys=["a", "b", "  UNNAMED33", "newB"], returnItemNames=["a", "b", "newB"], _rows=2, _db_hits=0)
      Extract(symKeys=["a", "b", "  UNNAMED33"], exprKeys=["newB"], _rows=2, _db_hits=0)
        PatternMatch(g="(a)-['  UNNAMED33']-(b)", _rows=2, _db_hits=1)
          PatternMatch(g="", _rows=2, _db_hits=0)
            Filter(pred="hasLabel(a: timeline)", _rows=2, _db_hits=0)
              NodeByLabel(label="timeline", identifier="a", _rows=2, _db_hits=0)
第二个想法

MATCH a:timeline WITH a
MATCH a-[?]->b 
WHERE b.year? = 2010 
RETURN a, b AS year

Detailed Query Results
Query Results

+--------------------------------+
| a         | year               |
+--------------------------------+
| Node[7]{} | Node[8]{year:2010} |
| Node[9]{} |              |
+--------------------------------+
2 rows
2 ms

Execution Plan

ColumnFilter(symKeys=["a", "b", "  UNNAMED33", "year"], returnItemNames=["a", "year"], _rows=2, _db_hits=0)
Extract(symKeys=["a", "b", "  UNNAMED33"], exprKeys=["year"], _rows=2, _db_hits=0)
  Filter(pred="nullable([($anonfun$nullableProperty$3$$anonfun$apply$21$$anon$1,true)],[$anonfun$nullableProperty$3$$anonfun$apply$21$$anon$1 == Literal(2010)])", _rows=2, _db_hits=2)
    PatternMatch(g="(a)-['  UNNAMED33']-(b)", _rows=2, _db_hits=3)
      PatternMatch(g="", _rows=2, _db_hits=0)
        Filter(pred="hasLabel(a: timeline)", _rows=2, _db_hits=0)
          NodeByLabel(label="timeline", identifier="a", _rows=2, _db_hits=0)

如果我们在Cypher中有一个NULLIF函数,那么这会更简洁一些。尽管在这两种情况下,在检查关系上的节点时,它看起来都没有使用任何索引。

这个问题的正确答案是,Neo4j 2.0.0 Milestone 03中没有此功能或缺少此功能(bug?)。但现在已添加到Neo4j 2.0.0里程碑05中<代码>可选节点上的标签不再阻止整个MATCH子句返回结果。

资料来源:


(我还没有测试过这一点)

是的,当然更愿意贡献。这会利用已经发布的索引吗?或者,在对所有节点执行搜索后,是否会执行该案例?您是否询问它是否会使用标签上的索引或属性上的索引?我猜,即使是非可选的,它也必须首先在标签上做一个WHERE。根据您发布的执行计划,我现在知道,使用我的原始解决方案并没有降低性能。因为在我的当前方案中,我实际上不依赖标签进行标识(下一个节点总是有相同的标签),所以对于我的用例,权衡仅仅是查询的清晰度。在这种情况下,我将采用我已有的解决方案。谢谢你的调查,我会接受你的回答。是的,我们希望将来它会使用可选标签。