2

我有一个包含作者的巨大图形数据库,它们连接到论文,论文连接到包含论文元信息的节点。我试图选择与特定模式匹配的作者,因此我在 java 中执行了以下 cypher 语句。

String query = "MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n";
db.execute(query);

我得到一个包含所有“作者”的结果集。但是执行速度很慢。是不是因为 Neo4j 将结果写入内存?

如果我尝试使用 Java API 查找节点,它会快得多。当然,我只能像下面的代码示例那样搜索确切的名称,但它比上面的查询快了大约 4 秒。我在一个大约有 50 个节点的小型数据库上对其进行了测试,其中只有 6 个节点是作者。六位作者也在索引中。

db.findNodes(NodeLabel.AUTHOR, NodeProperties.NAME, "jim knopf" );

有没有机会加快密码?或者有可能通过 Java API 和findNodes()方法获取所有节点,这些节点与给定模式匹配?

仅供参考,我在 java 中创建了作者姓名的索引graph.schema().indexFor(NodeLabel.AUTHOR).on("name").create();

也许有人可以帮忙。提前致谢。

编辑:

我今天进行了一些测试。如果我在浏览器界面中执行查询PROFILE MATCH (n:AUTHOR) WHERE n.name = 'jim seroka' RETURN n;,我只有运算符NodeByLabelScan。在我看来,Neo4j 不会自动使用索引(名称索引在线)。如果我使用特定索引并执行查询PROFILE MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n;,则将使用该索引。通常 Neo4j 应该自动使用正确的索引。有什么配置可以设置吗?

我还再次在嵌入模式下做了一些测试,以检查嵌入模式下查询的性能。我试图选择作者“jim seroka” db.findNode(NodeLabel.AUTHOR, "name", "jim seroka");。它有效,在我看来,由于执行时间约为 0.05 秒,因此使用了索引。

但是,如果我运行相同的查询,就像我在界面中执行的和前面提到的那样,使用特定的索引,它需要大约 4.9 秒。为什么?我有点无助。该数据库是本地的,只有 6 个作者。连接器速度慢还是连接创建错误?好的,findNode()是否只返回一个节点并执行整个结果,但相差四秒?

以下源代码应显示如何创建数据库和执行查询。

public static GraphDatabaseService getNeo4jDB() {
    ....
    return new GraphDatabaseFactory().newEmbeddedDatabase(STORE_DIR);
}

private Result findAuthorNode(String searchValue) {
    db = getNeo4jDB();

    String query = "MATCH (n:AUTHOR) USING INDEX n:AUTHOR(name) WHERE n.name = 'jim seroka' RETURN n";

    return db.execute(query);
}
4

1 回答 1

2

您的查询使用正则表达式,因此无法使用索引:

MATCH (n:AUTHOR) WHERE n.name =~ '(?i).*jim.*' RETURN n

Neo4j 2.3 引入了支持索引STARTS WITH的字符串运算符,因此该查询将非常高效:

MATCH (n:Author) WHERE n.name STARTS WITH 'jim' RETURN n

与正则表达式不太一样,但性能会更好。

于 2015-12-21T17:12:34.307 回答