1

我们正在开发一个基于的应用程序,大约有200k个节点,每个节点都有一个属性,例如type='user'type='company' 表示我们应用程序的特定实体。我们需要获取图中特定类型的所有节点的计数。

我们为每个实体创建了一个索引,例如userscompanies它包含该属性的节点。所以内部users索引驻留130K节点,其余在companies.

使用 Cypher,我们可以像这样查询。

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

结果是

Returned 1 row.Query took 4080ms

服务器配置为默认值,稍作调整,但 4 秒也满足我们的需要。认为数据库会在 1 个月内增长 20K,所以我们非常非常需要这个查询执行。

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

非常感谢,对不起我糟糕的英语。

4

4 回答 4

3

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

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

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

再次感谢大家。

于 2012-10-24T03:41:48.807 回答
1

嗯,这真的是关于那个 Lucene 索引的性能。如果您大部分时间只需要这个单一查询,为什么不使用某个节点上某个节点上的总数更新一个整数,并且可能与索引插入一起更新它,为了更好的措施,每晚使用上面的查询运行更新就可以了?

于 2012-08-02T17:27:56.133 回答
0

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

交易 tx = db.beginTx();
尝试 {
    ...
    ...
    tx.acquireWriteLock(countingNode);
    countNode.setProperty("user_count",
        ((整数)countingNode.getProperty("user_count"))+1);
    tx.成功();
} 最后 {
    tx.finish();
}
于 2012-08-02T18:40:47.990 回答
0

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

company1-[:IS_ENTITY]->公司实体

或者,如果您使用的是 2.0

公司1:公司

顺便说一下,第二个还允许您在单独的后台线程中自动更新索引,这是 imo 2.0 的最佳新功能之一

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

您的查询将如下所示:

v2.0

MATCH company:COMPANY
RETURN count(company)

v1.9

START entity=node:entityindex(value='company')
MATCH company-[:IS_ENTITIY]->entity
RETURN count(company)
于 2013-07-03T10:32:37.030 回答