我们正在开发一个基于neo4j和php的应用程序,其中包含 200k 个节点,每个节点都有type='user'
或{{1}这样的属性表示我们的应用程序的特定实体。我们需要获得图中特定类型的所有节点的计数。
我们为type='company'
,users
等每个实体创建了一个索引,其中包含该属性的节点。因此,companies
内部的索引位于 130K 节点,其余位于users
。
对于Cypher,我们这样查询。
companies
结果是
START u=node:users('id:*')
RETURN count(u)
服务器配置为默认设置,略有调整,但4秒也是我们的需求。认为数据库将在1个月20K内增长,因此我们需要这个查询执行非常多。
有没有其他方法可以做到这一点,可能与Gremlin,或与其他一些服务器插件? 我将缓存这些结果,但我想知道是否可以调整它。
非常感谢,抱歉我的英语很差。
答案 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)