4

我正在尝试在 Neo4j http://blog.neo4j.org/2012/02/modeling-multilevel-index-in-neoj4.html中构建这个模型

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

理想情况下,我想要这个查询:

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

如果没有 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 控制台或数据浏览器中无效。我认为这些将是“完美无缺的”,因此之前没有在我的代码中测试这些查询。控制台和数据浏览器给出不同的结果也很奇怪。在开始时选择 node(*) 而不是 node(1) 并没有什么不同。

更新 2:我对 Peter Neubauer 发布的示例要点进行了更多尝试。问题是这个例子返回了每一个或什么都没有。虽然我想让返回的列成为可选的。所以在这个例子中,我希望 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

我得到(在要点网站上):

 Error: java.lang.NullPointerException

这是踢球者:这只发生在 Firefox 上,在 chrome 上返回:查询花费 1 毫秒并且没有返回任何行。

然后这个查询:

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 种不同的环境给出不同的结果:

我还没有尝试过:

  • 以批处理文件开头的控制台
  • 使用 Opera的要点网站http://gist.neo4j.org
  • http://console.neo4j.org/上的 neo4j 控制台(我希望这会给出与要点相同的结果,因为它看起来相同,但我尚未对此进行测试)

所以我对查询和一堆环境有很多变化。也许这可以编写脚本以使查询在不同的环境中运行并返回结果。然后我可以将结果放在一个表中,其中一个轴是环境,另一个轴是被测查询。

4

4 回答 4

1

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

CASE
    WHEN b IS NOT NULL AND ANY(x IN LABELS(b) WHERE x="time_year") THEN b
    ELSE NULL 
END AS newB

由于 b 是任何类型的节点,这将确保如果它存在,它就是正确的标签。这有点冗长,但是哦。

--edit-- 基于 Flip 对 index 的评论,我做了以下事情:(执行计划基于每个查询的第二次运行)

CREATE INDEX ON :time_year(year);
create 
(_7:timeline ),
(_8:time_year  {year:2010}),
(_9:timeline ),
_9-[:HAS_YEAR]->_8;

第一个想法

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 函数,这会使这变得更简洁一些。尽管在任何一种情况下检查关系上的节点时,它看起来都没有使用任何索引。

于 2013-08-08T22:13:31.750 回答
0

从这个页面得到答案:http: //grokbase.com/t/gg/neo4j/137qbdyn14/use-label-in-start

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

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

于 2013-07-28T20:27:05.910 回答
0

这个问题的正确答案是 Neo4j 2.0.0 Milestone 03 中没有此功能或缺少此功能(错误?)。但现在已添加到 Neo4j 2.0.0 Milestone 05。Labels on optional nodes no longer stop the whole MATCH clause from returning results.

来源:https ://github.com/neo4j/neo4j/blob/master/packaging/standalone/standalone-community/src/main/distribution/text/community/CHANGES.txt

(我还没有测试过)

于 2013-09-25T17:42:48.827 回答
-1

我对此做了一个图表要点,请参阅http://gist.neo4j.org/?6113785并且标签似乎正在工作。想要贡献和澄清吗?

于 2013-07-30T15:21:02.583 回答