4

我有一个想要查询的旧数据集(以 GraphML 表示的ENRON 数据)。在相关问题的评论中, @StefanArmbruster建议我使用 Cypher 来查询数据库。我的查询用例很简单:给定消息 id(Message 节点的属性),检索具有该 id 的节点,并检索该消息的发送者和接收者节点。

似乎要在 Cypher 中执行此操作,我首先必须创建节点的索引。当从 graphML 文件加载数据时,有没有办法自动执行此操作?(我曾使用 Gremlin 加载数据并创建数据库。)

我还有一个数据的外部 Lucene 索引(我需​​要它用于其他目的)。有两个索引有意义吗?例如,我可以将 Neo4J 节点 ID 索引到我的外部索引中,然后根据这些 ID 查询图形。我担心的是这些 id 的持久性。(以此类推,不应将 Lucene 文档 ID 视为持久性。)

那么,我应该:

  1. 在内部索引 Neo4j 图以使用 Cypher 查询消息 ID?(如果是这样,最好的方法是什么:用一些合适的咒语重新生成数据库以建立索引?在已经存在的数据库上建立索引?)

  2. 将 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。

4

2 回答 2

2

自动索引是懒惰地创建的。也就是说 - 当您启用自动索引时,实际索引是在您索引您的第一个属性时首先创建的。确保在检查索引是否存在之前插入数据,否则它可能不会显示。

对于一些自动索引代码(使用编程配置),请参阅例如https://github.com/neo4j-contrib/rabbithole/blob/master/src/test/java/org/neo4j/community/console/IndexTest.java(这适用于 Neo4j 1.8

/彼得

于 2012-11-01T05:11:05.933 回答
0

您是否尝试过自动索引功能?它基本上是您正在寻找的用例——不幸的是,它需要在您导入数据之前启用。(否则,您必须删除/添加属性以重新索引它们。)

http://docs.neo4j.org/chunked/milestone/auto-indexing.html

于 2012-11-01T00:21:42.333 回答