【问题标题】:Neo4j indexes and legacy dataNeo4j 索引和遗留数据
【发布时间】:2012-10-31 23:13:05
【问题描述】:

我有一个想要查询的旧数据集(ENRON data 表示为 GraphML)。在一个相关问题的comment 中,@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 和嵌入式服务器一起使用,但没有成功。在documentation 它说

底层数据库是自动索引的,请参阅第 14.12 节,“自动索引”,因此脚本可以通过索引查找返回导入的节点。

但是当我在加载新数据库后检查图表时,似乎不存在任何索引。

Neo4j documentation on auto indexing 表示需要进行大量配置。除了设置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 documentation 中给出的示例,因此我的数据库创建是这样的(在 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();

这似乎奏效了。但是请注意,对Neo4jGraph 对象的getIndices() 调用仍然返回一个空列表。所以结果是我可以正确使用 Neo4j API,但 Gremlin 包装器似乎无法反映索引状态。表达式g.idx('node_auto_index')(记录在Gremlin Methods)返回null。

【问题讨论】:

    标签: neo4j cypher gremlin


    【解决方案1】:

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

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

    /彼得

    【讨论】:

    • 我再次修改了问题,以表明在创建 Neo4jGraph 实例后,我从 graphml 文件加载数据。加载成功,因为我可以遍历图表,但通过 getIndices() 枚举索引会导致一个空列表。
    • 所以,我不认为自动索引被列出,因为它是一个内置的。你能用它搜索东西吗?
    • 是的,事实证明,自动索引确实有效。它确实认为它没有在其他索引中列举出来是违反直觉的。
    【解决方案2】:

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

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

    【讨论】:

    • 我一直在沿着这条路慢慢前进,但并没有走得太远。我已更新问题以反映我目前缺乏进展。
    • 嗯,不幸的是,我没有做很多嵌入式工作。这对于 REST 服务来说是微不足道的。我看看能不能找人回答一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    • 2016-02-15
    • 1970-01-01
    相关资源
    最近更新 更多