【发布时间】:2016-08-18 22:04:28
【问题描述】:
假设我有一个性质的 neo4j 图:
create (SK:Author {name:'Stephen King'}), (JK:Author {name:'J.K. Rowling'}), (DS:Author {name:'Dr. Seuss'}), (TS:Book {name:'The Stand'}), (HP:Book {name:'Harry Potter'}), (CH:Book {name:'Cat in the Hat'}), (SHINING:Book {name:'The Shining'}), (PAF:Genre {name:'Post-Apocalyptic fiction'}), (F:Genre {name:'Fantasy'}), (C:Genre {name:'Childrens'}), (HORROR:Genre {name:'Horror'}), (SK)<-[:WRITTEN_BY]-(TS)-[:CATEGORIZED_AS]->(PAF), (JK)<-[:WRITTEN_BY]-(HP)-[:CATEGORIZED_AS]->(F), (DS)<-[:WRITTEN_BY]-(CH)-[:CATEGORIZED_AS]->(C), (SK)<-[:WRITTEN_BY]-(SHINING)-[:CATEGORIZED_AS]->(HORROR)
Neo4j 控制台链接:http://console.neo4j.org/r/2d69kq
我有大约 53,000 个作者节点、600 万个书籍节点和 9,000 个流派节点。
对于这样的查询:
match (b:Book)-[:WRITTEN_BY]->(a:Author)
where a.name in ['Stephen King', 'J.K. Rowling']
with a, collect(b) as bs
unwind bs as book
match (g:Genre)<-[r:CATEGORIZED_AS]-(book)
where id(g) in [13, 14, 15, 16]
with a, count(distinct book) as book_count_author, collect(book) as bs
unwind bs as book
match (g:Genre)<-[r:CATEGORIZED_AS]-(book)
where id(g) in [13, 14, 15, 16]
return a.name, g.name, count(distinct book) as book_count_genre, book_count_author
大约需要 12 秒才能完成。我试图用几种不同的方式重写查询并使用索引提示,但无法找出任何让它更快的方法。有什么想法吗?显然这个例子被简化了,但我确实有相应属性的索引。
我需要两个聚合。第一个是作者的书籍数量,受第二场比赛中指定类型的限制。第二个计数是每个作者在每个类型中的书籍,再次受到相同类型的限制。
【问题讨论】:
-
您的 id 对于我们这些试图在我们自己的系统上重新创建它的人来说是不可移植的(neo4j 内部 ID 永远不应该在外部使用,因为它们可能会更改,并且 id 可以被系统重用)。请修改您的查询以不使用 id 进行匹配。
-
您能否也显示索引和约束的架构?
-
Re: ids,你可以使用链接的neo4j控制台,应该保留ids。这不是我的真实模式,但具有代表性。我无法分享真实的架构。我确实对正在使用的列有索引,并且在执行配置文件中看不到任何扫描。
-
所以让我看看我是否理解您的要求...book_count_genre 应该是该类型的书籍总数,与作者无关,而 book_count_author 是给定的该类型的书籍数量作者?
-
我包含的表格是我期望的结果。 book_count_author 是作者在所有受限类型中所写书籍的总数。 book_count_genre 是在所有受限类型中按类型和作者分类的图书数量。
标签: neo4j