クエリを実行したいレガシー データセット ( GraphML として表されるENRON データ) があります。関連する質問のコメントで、 @StefanArmbrusterは、Cypher を使用してデータベースにクエリを実行することを提案しています。私のクエリのユース ケースは単純です。メッセージ ID (メッセージ ノードのプロパティ) を指定すると、その ID を持つノードを取得し、そのメッセージの送信者ノードと受信者ノードも取得します。
Cypher でこれを行うには、まずノードのインデックスを作成する必要があるようです。データがgraphMLファイルからロードされたときにこれを自動的に行う方法はありますか? (Gremlin を使用してデータをロードし、データベースを作成しました。)
データの外部 Lucene インデックスもあります (他の目的で必要です)。2 つのインデックスを持つことは理にかなっていますか? たとえば、Neo4J ノード ID を外部インデックスにインデックス化し、それらの ID に基づいてグラフをクエリできます。私の懸念は、これらの ID の持続性です。(類推すると、Lucene ドキュメント ID は永続的なものとして扱われるべきではありません。)
だから、私はすべきですか:
Cypher を使用してメッセージ ID を照会するために、内部的に Neo4j グラフにインデックスを付けますか? (もしそうなら、それを行う最善の方法は何ですか:インデックスを構築するための適切な呪文でデータベースを再生成しますか?既存のデータベースにインデックスを構築しますか?)
Neo4j ノード ID を外部 Lucene インデックスに保存し、これらの保存された ID を介してノードを取得しますか?
アップデート
Gremlin と組み込みサーバーで自動インデックス作成を機能させようとしましたが、うまくいきませんでした。ドキュメントでは、それは言う
基礎となるデータベースは自動索引付けされます。セクション14.12「自動索引付け」を参照してください。これにより、スクリプトは索引ルックアップによってインポートされたノードを返すことができます。
しかし、新しいデータベースをロードした後にグラフを調べると、インデックスが存在しないようです。
自動インデックス作成に関する Neo4jのドキュメントには、一連の構成が必要であると書かれています。設定に加えてnode_auto_indexing = true
、構成する必要があります
実際に自動インデックスを作成するには、インデックスを作成するプロパティを設定する必要があります。これを行うには、インデックスを作成するプロパティ キーをリストします。構成ファイルで、node_keys_indexable および relationship_keys_indexable 構成キーを使用します。埋め込みモードを使用する場合は、GraphDatabaseSettings.node_keys_indexable および GraphDatabaseSettings.relationship_keys_indexable 構成キーを使用します。いずれの場合も、値は、インデックスを作成するプロパティ キーのカンマ区切りのリストにする必要があります。
では、Gremlin はGraphDatabaseSettings
パラメーターを設定することになっているのでしょうか? 次のように、Neo4jGraph コンストラクターにマップを渡そうとしました。
Map<String,String> config = [
'node_auto_indexing':'true',
'node_keys_indexable': 'emailID'
]
Neo4jGraph g = new Neo4jGraph(graphDB, config);
g.loadGraphML("../databases/data.graphml");
しかし、インデックスの作成には明らかな影響はありませんでした。
更新 2
Gremlin を使用してデータベースを構成するのではなく、Neo4j のドキュメントに記載されている例を使用して、データベースの作成が次のようになるようにしました (Groovy で)。
protected Neo4jGraph getGraph(String graphDBname, String databaseName) {
boolean populateDB = !new File(graphDBName).exists();
if(populateDB)
println "creating database";
else
println "opening database";
GraphDatabaseService graphDB = new GraphDatabaseFactory().
newEmbeddedDatabaseBuilder( graphDBName ).
setConfig( GraphDatabaseSettings.node_keys_indexable, "emailID" ).
setConfig( GraphDatabaseSettings.node_auto_indexing, "true" ).
setConfig( GraphDatabaseSettings.dump_configuration, "true").
newGraphDatabase();
Neo4jGraph g = new Neo4jGraph(graphDB);
if (populateDB) {
println "Populating graph"
g.loadGraphML(databaseName);
}
return g;
}
私の検索は次のように行われました:
ReadableIndex<Node> autoNodeIndex = graph.rawGraph.index()
.getNodeAutoIndexer()
.getAutoIndex();
def node = autoNodeIndex.get( "emailID", "<2614099.1075839927264.JavaMail.evans@thyme>" ).getSingle();
そして、これはうまくいくように見えました。ただし、オブジェクトのgetIndices()
呼び出しNeo4jGraph
は空のリストを返したことに注意してください。結果として、Neo4j API を正しく実行できますが、Gremlin ラッパーはインデックス作成状態を反映できないようです。式g.idx('node_auto_index')
( Gremlin Methodsに記載) は null を返します。