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(1) の代わりに node(*) を選択しても違いはありません。

更新 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

私は(Gists Webサイトで)取得します:

 Error: java.lang.NullPointerException

ここにキッカーがあります: これは Firefox でのみ発生し、クロムではこれが返されます: クエリは 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つの異なる環境があります。

  • jadellによるphp4neojを使用した独自のコード作成
  • データ ブラウザを使用した Web インターフェイス
  • コンソールを使用した Web インターフェイス
  • Gists Web サイトhttp://gist.neo4j.orgと Firefox を使用
  • Chrome を使用した Gists ウェブサイトhttp://gist.neo4j.org

私はまだ試していません:

  • バッチファイルで始まるコンソール
  • Opera を使用した gists ウェブサイトhttp://gist.neo4j.org
  • http://console.neo4j.org/の neo4j コンソール(見た目は同じなので要点と同じ結果になると思いますが、まだテストしていません)

だから私はクエリと環境の束にたくさんのバリエーションがあります。おそらく、これは、さまざまな環境でクエリを実行して結果を返す方法でスクリプト化できる可能性があります。次に、1 つの軸が環境で、もう 1 つの軸がテスト中のクエリであるテーブルに結果を入れることができます。

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-- インデックスに関するフリップのコメントに基づいて、次のことを行いました: (実行計画は、各クエリが 2 回目に実行されることに基づいています)

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 に答える