任何人都知道在Neo4j中查询多个路径的快捷方法吗?
让我说我的电影节点可以有一个我想要匹配的类型(这是伪代码)
MATCH
(m:Movie)<-[:TYPE]-(g:Genre { name:'action' })
OR
(m:Movie)<-[:TYPE]-(x:Genre)<-[:G_TYPE*1..3]-(g:Genre { name:'action' })
(m)-[:SUBGENRE]->(sg:SubGenre {name: 'comedy'})
OR
(m)-[:SUBGENRE]->(x)<-[:SUB_TYPE*1..3]-(sg:SubGenre {name: 'comedy'})
问题是,第一个&#34; m:电影&#34;要匹配的节点必须与指定的路径之一匹配,第二个SubGenre在第一个匹配时依赖。 我可以创建一个使用MATCH和WHERE工作的查询,但它真的很慢(使用20MB的小数据集时为30秒)。
问题是,我不知道如何在Neo4j中匹配OR与其他OR匹配的第一个结果。
如果我使用WHERE,那么我必须声明在任何语句中使用的所有节点,在初始MATCH中使查询变慢(因为你不能在WHERE中引入新节点)
任何人都知道解决这个问题的优雅方法吗?谢谢!
答案 0 :(得分:1)
也许OPTIONAL MATCH
clause可能对此有所帮助。 OPTIONAL MATCH
beavior类似于MATCH
语句,除了代替全有或无模式匹配方法之外,模式中与语句中特定模式不匹配的任何元素都绑定为null 。
例如,要匹配电影,其类型和可能的子类型:
OPTIONAL MATCH (m:Movie)-[:IS_GENRE]->(g:Genre)<-[:IS_SUBGENRE]-(sub:Genre)
WHERE m.title = "The Matrix"
RETURN m, g, sub
这将返回电影节点,流派节点,如果存在,则返回子流派。如果没有子流派,那么它将为sub
返回null。您可以使用上面的可变长度路径以及OPTIONAL MATCH
。
答案 1 :(得分:1)
您可以尝试长度最小为0的可变长度路径:
MATCH
(m:Movie)<-[:TYPE|:SUBGENRE*0..4]-(g)
WHERE g:Genre and g.name = 'action' OR g:SubGenre and g.name='comedy'
对于使用索引查找类型/子类型的查询,我建议使用UNION查询。
MATCH
(m:Movie)<-[:TYPE*0..4]-(g:Genre { name:'action' })
RETURN distinct m
UNION
(m:Movie)-[:SUBGENRE]->(x)<-[:SUB_TYPE*1..3]-(sg:SubGenre {name: 'comedy'})
RETURN distinct m
答案 2 :(得分:1)
[EDITED]
以下MATCH
子句应与您的伪代码等效。为了提高效率,还有一个USING INDEX
子句假设您在:SubGenre(name)
上有第一个created an index。 (如果:Genre(name)
节点比Genre
个节点多,则可以使用SubGenre
上的索引。)
MATCH
(m:Movie)<-[:TYPE*0..4]-(g:Genre { name:'action' }),
(m)-[:SUBGENRE]->()<-[:SUB_TYPE*0..3]-(sg:SubGenre { name: 'comedy' })
USING INDEX sg:SubGenre(name)
Here is a console显示某些示例数据的结果。