试图找到具有可变长度关系和cpyher

时间:2017-11-01 18:27:32

标签: neo4j cypher

在我的数据库中,我有标记了标记的资源。标签可以在其他标签内(即' neo4j'将连接到'数据库'像这样:(neo4j:tag)-[:WITHIN]->(databases:tag)),但并非所有标签都有父母。如果资源通过以下查询直接或间接(通过子级)连接到资源,则会返回资源:

MATCH (re:resource)-[:TAGGED_WITH]->(:tag)-[:WITHIN_TAG*0..3]->(parent:tag)
WHERE u.uid IN {includedTags}
RETURN DISTINCT re;

这个问题是,如果用户搜索多个标记(即' neo4j'和#39;数据库'),如果它们与任何搜索标记匹配,则会返回这些资源。我想要的是只有匹配所有返回的资源。这将允许搜索范围缩小,因为搜索的标签越多,而不是扩展。

在使用可变长度路径(仅返回直接用所有搜索标签标记的资源)之前,我通过跟踪连接标签的数量实现了这一目标:

WITH DISTINCT re, count(*) AS connected 
WHERE connected = SIZE({includedSets}) 

我无法在这里弄清楚如何做类似的事情。

1 个答案:

答案 0 :(得分:3)

使用all predicate function

MATCH (re:resource)-[:TAGGED_WITH]->(:tag)-[:WITHIN_TAG*0..3]->(parent:tag)
WITH re, collect(parent) AS parentTags
WHERE all(tag IN {includedTags} WHERE tag IN parentTags)
RETURN re;

在性能方面,这可能不是最好的解决方案,但首先,让我们看看它是否有效。

如果您通过了uid检查,请收集父母的这些属性:

MATCH (re:resource)-[:TAGGED_WITH]->(:tag)-[:WITHIN_TAG*0..3]->(parent:tag)
WITH re, collect(parent.uid) AS parentTags
WHERE all(tag IN {includedTags} WHERE tag IN parentTags)
RETURN re;

如果资源包含许多标记,则此优化可能有所帮助:

WITH {includedTags} as includedTags
UNWIND includedTags as tagId
MATCH (re:resource)-[:TAGGED_WITH]->(:tag)-[:WITHIN_TAG*0..3]->(parent:tag {uid: tagId})
WITH re, includedTags, count(parent) AS parentTags
WHERE size(includedTags) = parentTags
RETURN re;