加速neo4j cypher查询

时间:2014-07-07 09:46:10

标签: neo4j cypher

我有一个带有ruby on rails的嵌入式neo4j服务器。

这些是配置:

neostore.nodestore.db.mapped_memory=25M
neostore.relationshipstore.db.mapped_memory=240M
neostore.propertystore.db.mapped_memory=230M
neostore.propertystore.db.strings.mapped_memory=1200M
neostore.propertystore.db.arrays.mapped_memory=130M

wrapper.java.initmemory=1024
wrapper.java.maxmemory=2048

15lakh个电影节点。以下查询正在执行5secs

MATCH (movie:Movie) 
WITH movie, toInt(movie.reviews_count) + toInt(movie.ratings_count) AS weight 
RETURN movie, weight as weight 
ORDER BY weight DESC 
SKIP skip_count 
LIMIT 10

此处skip_count随着用户滚动结果而变化。

另一个旨在从特定导演那里获取电影的查询需要9secs

MATCH (movie:Movie) , (director:Director)-[:Directed]->(movie) 
WHERE  director.name =~ '(?i)DIRECTOR_NAME' 
WITH movie, toInt(movie.ratings_count) * toInt(movie.reviews_count) * toInt(movie.rating) AS total_weight
RETURN movie, total_weight 
ORDER BY total_weight DESC, movie.rating DESC  
LIMIT 10 

如何缩短查询执行时间?

1 个答案:

答案 0 :(得分:2)

关于第一个查询:

您可以通过按权重降序使用:NEXT_WEIGHT关系连接所有电影节点,使图表中的权重排序明确,这样电影就会构建链接列表。

您的查询如下:

 MATCH p=(:Movie {name:'<name of movie with highest weight>'})-[:NEXT_WEIGHT*..1000]-()
 WHERE length(p)>skip_count AND length(p)<skip_count+limit
 WITH p
 ORDER BY length(p)
 WITH last(nodes(p)) as movie
 RETURN movie, toInt(movie.reviews_count) + toInt(movie.ratings_count) AS weight 

关于第二个查询:

您应该使用索引来加速导演查找。不幸的是,索引查找目前仅支持精确查找。因此要么确保搜索字符串在大写/小写方面是正确的,要么将标准化版本存储在另一个属性中:

MATCH (d:Director) set d.lowerName = LOWER(d.name)

确保标签Director和属性LowerName上有索引:

CREATE INDEX ON :Director(lowerName)

您的查询应如下所示:

MATCH (director:Director)-[:Directed]->(movie) 
WHERE director.name = {directorName}
RETURN movie, toInt(movie.ratings_count) * toInt(movie.reviews_count) *         toInt(movie.rating) AS total_weight
ORDER BY total_weight DESC, movie.rating DESC  
LIMIT 10