neo4j计算节点在200K节点和450K关系上的性能

时间:2012-08-02 16:52:10

标签: indexing neo4j gremlin cypher

我们正在开发一个基于的应用程序,其中包含 200k 个节点,每个节点都有type='user'或{{1}这样的属性表示我们的应用程序的特定实体。我们需要获得图中特定类型的所有节点的计数。

我们为type='company'users等每个实体创建了一个索引,其中包含该属性的节点。因此,companies内部的索引位于 130K 节点,其余位于users

对于Cypher,我们这样查询。

companies

结果是

START u=node:users('id:*')
RETURN count(u)

服务器配置为默认设置,略有调整,但4秒也是我们的需求。认为数据库将在1个月20K内增长,因此我们需要这个查询执行非常多。

有没有其他方法可以做到这一点,可能与Gremlin,或与其他一些服务器插件? 我将缓存这些结果,但我想知道是否可以调整它。

非常感谢,抱歉我的英语很差。

4 个答案:

答案 0 :(得分:3)

最后,我使用Gremlin而不是Cypher,找到了解决方案。

g.getRawGraph().index().forNodes('NAME_OF_USERS_INDEX').query(
    new org.neo4j.index.lucene.QueryContext('*')
).size()

此方法使用lucene索引来获取“近似”行。

再次感谢所有人。

答案 1 :(得分:1)

Mmh的, 这真的是关于Lucene指数的表现。如果你大多数时候只需要这个单一的查询,为什么不在某个节点更新某个节点上的总计数的整数,并且可能与索引插入一起更新,为了更好的衡量,每天晚上运行一个带有上面查询的更新?

答案 2 :(得分:0)

您可以使特定节点上的属性与此类节点的数量保持同步,其中更新由写锁保护:

Transaction tx = db.beginTx();
try {
    ...
    ...
    tx.acquireWriteLock( countingNode );
    countingNode.setProperty( "user_count",
        ((Integer)countingNode.getProperty( "user_count" ))+1 );
    tx.success();
} finally {
    tx.finish();
}

答案 3 :(得分:0)

如果您想获得最佳性能,请不要将实体类别建模为节点上的属性。相反,这样做:

公司1 - [:IS_ENTITY] - GT; companyentity

或者如果您使用的是2.0

公司1:COMPANY

第二个也允许你在一个单独的后台线程中自动更新你的索引,这是2.0的最佳新功能之一

第一种方法也应该证明更有效,因为制作“跳”通常比从节点读取属性花费的时间更少。但是,它确实需要您为实体创建单独的索引。

您的查询将如下所示:

<强> 2.0

MATCH company:COMPANY
RETURN count(company)

<强> V1.9

START entity=node:entityindex(value='company')
MATCH company-[:IS_ENTITIY]->entity
RETURN count(company)