获取属于一组标签的所有电影

时间:2015-11-09 18:56:58

标签: neo4j cypher graph-databases

所以我有一部Neo4J数据库及其流派。我想找到所有类型的电影。

EG:

Matrix - Sci-fi, Thriller, Action
Harry Potter - Drama, Fiction, Thriller
Pulp Fiction - Drama, Thriller

现在,我想要的是属于Drama的电影,以及Thriller。 这意味着Harry和Pulp,但不是Matrix,尽管它也属于Thriller。

关于查询的任何想法?

3 个答案:

答案 0 :(得分:2)

您可MATCH MovieGenre个节点,并过滤两个MATCH (m:Movie) WHERE (m)-[:GENRE]->(:Genre {genre_name: 'Drama'}) AND (m)-[:GENRE]->(:Genre {genre_name: 'Thriller'}) RETURN m 个节点的关系:

$('html, body').animate({
    scrollTop: $("{{ str_replace(' ', '-', $element['title']) }}").offset().top
}, 2000);

答案 1 :(得分:1)

  1. 正如您在评论中提到的那样,您不需要在每个方向(containsgenres)建立关系。只有一个方向是足够好的,因为你可以很容易地在任何一个方向上穿越关系。在这个答案中,我将使用genre关系。

  2. 我假设您首先在name节点的Genre属性上创建索引。

    CREATE INDEX ON :Genre(name);
    

    此索引将允许下面的实际查询快速获取所需的Genre节点,而无需遍历每个此类节点。

    MATCH (g1:Genre { name: 'Drama' })<-[:genre]-(m:Movie)-[:genre]->(g2:Genre { name: 'Thriller' })
    USING INDEX g1:Genre(name)
    USING INDEX g2:Genre(name)
    RETURN m;
    

    这个简单而有效的查询强制(通过USING INDEX)Cypher规划器为两个Genre节点使用上述索引(因为规划器当前只对其中一个节点自动执行此操作)。

答案 2 :(得分:0)

考虑以下数据集:

Create (g1:Genre {name: 'Sci-fi' } )
Create (g2:Genre {name: 'Thriller' } )
Create (g3:Genre {name: 'Action' } )
Create (g4:Genre {name: 'Drama' } )
Create (g5:Genre {name: 'Fiction' } )
Create (m1:Movie {name: 'Matrix' } )
Create (m1)-[:IS_GENRE]->(g1)
Create (m1)-[:IS_GENRE]->(g2)
Create (m1)-[:IS_GENRE]->(g3)
Create (m2:Movie {name: 'Harry Potter' } )
Create (m2)-[:IS_GENRE]->(g4)
Create (m2)-[:IS_GENRE]->(g5)
Create (m2)-[:IS_GENRE]->(g2)
Create (m3:Movie {name: 'Pulp Fiction' } )
Create (m3)-[:IS_GENRE]->(g4)
Create (m3)-[:IS_GENRE]->(g2)

如果使用以下查询,则只能匹配特定列表中的流派,但只能返回每个电影的流派数量与列表大小相同的结果。

with ['Thriller','Drama'] as genre_list
match (m:Movie)-[r:IS_GENRE]->(g:Genre)
using index g:Genre(name)
where g.name in genre_list
with genre_list,m.name as movie, collect(g.name) as genres
where size(genres) = size(genre_list)
return movie, genres

我认为如果你只有两种类型匹配的话,这很有意思......

match p=allShortestPaths((g1:Genre {name: 'Thriller'} )-[:IS_GENRE*..2]-(g2:Genre {name: 'Drama'} ))
using index g1:Genre(name)
using index g2:Genre(name)
return (nodes(p)[1]).name as movie, [(nodes(p)[0]).name, (nodes(p)[2]).name] as genres