我正在玩Neo4J。我的数据由拥有标记对象的用户组成。我的架构看起来像:
(:User)-[:OWNS]->(:Object)-[:TAGGED_AS]->(:Tag)
我编写了一个脚本,可以生成一个示例图表。目前,我在数据库中有100个User
,~2500 Tag
和~10k Object
个节点。在那些我有约700k的关系之间。我知道希望查找不属于某个Object
的所有User
,但Tag
User
已经使用了MATCH (user:User {username: 'Cristal'})
WITH user
MATCH (user)-[:OWNS]->(obj:Object)-[:TAGGED_AS]->(tag:Tag)<-[:TAGGED_AS]-(other:Object)
WHERE NOT (user)-[:OWNS]->(other)
RETURN other
LIMIT 20
。查询看起来像:
{{1}}
然而,这个查询运行大约1-5分钟(取决于用户和他拥有多少个对象),这不仅是一个位慢。我究竟做错了什么?我认为这对于适度大小的图形来说是一个相当“微不足道”的查询。我正在使用Neo4J 2.1.6社区,并且已经将Java堆设置为2000 MB(我可以看到有一个Java进程使用这么多)。我错过了一个索引或类似的东西(我是Neo4J的新手)?
老实说,我认为结果几乎是即时的,特别是考虑到Neo4J文档提到我应该使用1到4 GB的堆来处理1亿个对象...而且我只接近1/100的这个号码。
如果是我的查询(我希望并期待),我该如何改进?在编写查询时你必须注意什么?
答案 0 :(得分:0)
你有用户名属性的索引吗?
CREATE INDEX ON :User(username)
你也不需要WITH
,所以可以放下它看看是否有帮助:
MATCH (user:User {username: 'Cristal'})-[:OWNS]->(obj:Object)-[:TAGGED_AS]->(tag:Tag)<-[:TAGGED_AS]-(other:Object)
WHERE NOT (user)-[:OWNS]->(other)
RETURN other
LIMIT 20
此外,我认为它不会有所不同,但您可以删除obj
和tag
变量,因为您没有在查询的其他位置使用它们。
另外,如果您要生成示例图表,可能需要查看GraphGen: