我有一个想要查询的旧数据集(以 GraphML 表示的ENRON 数据)。在相关问题的评论中, @StefanArmbruster建议我使用 Cypher 来查询数据库。我的查询用例很简单:给定消息 id(Message 节点的属性),检索具有该 id 的节点,并检索该消息的发送者和接收者节点。
似乎要在 Cypher 中执行此操作,我首先必须创建节点的索引。当从 graphML 文件加载数据时,有没有办法自动执行此操作?(我曾使用 Gremlin 加载数据并创建数据库。)
我还有一个数据的外部 Lucene 索引(我需要它用于其他目的)。有两个索引有意义吗?例如,我可以将 Neo4J 节点 ID 索引到我的外部索引中,然后根据这些 ID 查询图形。我担心的是这些 id 的持久性。(以此类推,不应将 Lucene 文档 ID 视为持久性。)
那么,我应该:
在内部索引 Neo4j 图以使用 Cypher 查询消息 ID?(如果是这样,最好的方法是什么:用一些合适的咒语重新生成数据库以建立索引?在已经存在的数据库上建立索引?)
将 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。