如何优化我的neo4j cypher查询?

时间:2016-12-06 09:29:12

标签: neo4j cypher

请检查下面的Cypher,我得到的结果是下面的查询()记录很少,但随着记录的增加,需要很长时间才能达到1601152毫秒: 我找到了添加USING INDEX的建议,并在查询中应用了USING INDEX

PROFILE MATCH (m:Movie)-[:IN_APP]->(a:App {app_id: '1'})<-[:USER_IN]-(p:Person)-[:WATCHED]->(ma:Movie)-[:HAS_TAG]->(t:Tag)<-[:HAS_TAG]-(mb:Movie)-[:IN_APP]->(a) 
USING INDEX a:App(app_id) WHERE p.person_id= '1' 
    AND NOT (p:Person)-[:WATCHED]-(mb) 
RETURN DISTINCT(mb.movie_id) , mb.title, mb.imdb_rating, mb.runtime, mb.award, mb.watch_count, COLLECT(DISTINCT(t.tag_id)) as Tag, count(DISTINCT(t.tag_id)) as matched_tags 
ORDER BY matched_tags DESC SKIP 0 LIMIT 50

你能帮我解决一下我能做什么吗?

我正在寻找基于标签推荐的100部电影,作为100部我不看的电影,并与我观看过的电影的标签相匹配。

1 个答案:

答案 0 :(得分:2)

以下查询可能对您更有效[假设您在:App(app_id):Person(person_id)都有索引。 顺便说一句,我认为在您的查询中,标识符ma应该是m(反之亦然)。

MATCH (m:Movie)-[:IN_APP]->(a:App {app_id: '1'})<-[:USER_IN]-(p:Person {person_id: '1'})-[:WATCHED]->(m)
WITH a, p, COLLECT(m) AS movies
UNWIND movies AS movie
MATCH (movie)-[:HAS_TAG]->(t)<-[:HAS_TAG]-(mb:Movie)-[:IN_APP]->(a)
WHERE NOT mb IN movies
WITH DISTINCT mb, t
RETURN mb.movie_id, mb.title, mb.imdb_rating, mb.runtime, mb.award, mb.watch_count, COLLECT(t.tag_id) as Tag, COUNT(t.tag_id) as matched_tags
ORDER BY matched_tags DESC SKIP 0 LIMIT 50;

如果您PROFILE此查询,您应该会看到它执行NodeIndexSeek次操作(而不是慢得多NodeByLabelScan)来快速执行第一个MATCH。该查询还收集指定人员监视的所有movies,并稍后使用该集合来加速WHERE子句(不再需要命中数据库)。此外,查询从一些节点模式中删除了一些标签(这样做似乎可能是明确的),以进一步加快处理速度。