如何编写密码查询以查找由特定标签标记的节点?
How to write a cypher query to find nodes tagged by specific tags?
数据库结构:
(:Event)-[:IS_TAGGED_BY]->(:EventTag {value})
结构评论:
- 有事件节点
- 有EventTag节点
- 标记节点有一个字符串 属性,称为 "value"
- 事件可以通过 IS_TAGGED_BY outgoing rel
标记
我需要编写一个查询,它将 return 仅那些由一组特定标签标记的事件。
这样的查询可能有两种变体,return:
- 事件,由至少一个指定的标签标记(我们称之为
findTaggedByAny
)。
- 事件,由所有指定的标签标记(我们称之为
findTaggedByAll
)。
我可以编写 findTaggedByAny
查询:
MATCH (et:EventTag)--(e:Event) WHERE et.value in {0} RETURN e
此处 {0} - 包含一组标记值的查询参数将被替换的位置。
因此,替换后查询将如下所示:
MATCH (et:EventTag)--(e:Event) WHERE et.value in ["tag1", "tag2"] RETURN e
但是我在尝试实现 findTaggedByAll
查询时遇到了困难,该查询也应该采用相同的参数和 return 事件,由集合中的所有标签标记。事件是否被任何其他标签标记并不重要。
[更新]
如果你想获取连接到数据库中所有标签的事件,你可以做一个高效的"degree-ness"检查,像这样(假设一个事件最多只连接一次到特定标签,IS_TAGGED_BY
关系仅用于将事件连接到标签):
MATCH (t:EventTag)
WITH COUNT(t) AS numTags
MATCH (e:Event)
WHERE SIZE((e)-[:IS_TAGGED_BY]->()) = numTags
RETURN e;
相反,如果您想获取在 tagList
参数中由 any 标记标记的事件:
MATCH (e:Event)-[:IS_TAGGED_BY]->(t:EventTag)
WHERE t.value IN $tagList
RETURN e;
相反,如果您想获取在 tagList
参数中由 所有 标记标记的事件:
MATCH (e:Event)-[:IS_TAGGED_BY]->(t:EventTag)
WITH e, COLLECT(t.value) AS tagValues
WHERE ALL(v IN tagValues WHERE v IN $tagList)
RETURN e;
此外,如果一个事件很少有那么多标签,这个较长的查询实际上可能会更快(通过在实际查看标签之前进行度数检查):
MATCH (e:Event)
WHERE SIZE((e)-[:IS_TAGGED_BY]->()) >= SIZE($tagList)
MATCH (e)-[:IS_TAGGED_BY]->(t:EventTag)
WITH e, COLLECT(t.value) AS tagValues
WHERE ALL(v IN tagValues WHERE v IN $tagList)
RETURN e;
数据库结构:
(:Event)-[:IS_TAGGED_BY]->(:EventTag {value})
结构评论:
- 有事件节点
- 有EventTag节点
- 标记节点有一个字符串 属性,称为 "value"
- 事件可以通过 IS_TAGGED_BY outgoing rel 标记
我需要编写一个查询,它将 return 仅那些由一组特定标签标记的事件。
这样的查询可能有两种变体,return:
- 事件,由至少一个指定的标签标记(我们称之为
findTaggedByAny
)。 - 事件,由所有指定的标签标记(我们称之为
findTaggedByAll
)。
我可以编写 findTaggedByAny
查询:
MATCH (et:EventTag)--(e:Event) WHERE et.value in {0} RETURN e
此处 {0} - 包含一组标记值的查询参数将被替换的位置。
因此,替换后查询将如下所示:
MATCH (et:EventTag)--(e:Event) WHERE et.value in ["tag1", "tag2"] RETURN e
但是我在尝试实现 findTaggedByAll
查询时遇到了困难,该查询也应该采用相同的参数和 return 事件,由集合中的所有标签标记。事件是否被任何其他标签标记并不重要。
[更新]
如果你想获取连接到数据库中所有标签的事件,你可以做一个高效的"degree-ness"检查,像这样(假设一个事件最多只连接一次到特定标签,
IS_TAGGED_BY
关系仅用于将事件连接到标签):MATCH (t:EventTag) WITH COUNT(t) AS numTags MATCH (e:Event) WHERE SIZE((e)-[:IS_TAGGED_BY]->()) = numTags RETURN e;
相反,如果您想获取在
tagList
参数中由 any 标记标记的事件:MATCH (e:Event)-[:IS_TAGGED_BY]->(t:EventTag) WHERE t.value IN $tagList RETURN e;
相反,如果您想获取在
tagList
参数中由 所有 标记标记的事件:MATCH (e:Event)-[:IS_TAGGED_BY]->(t:EventTag) WITH e, COLLECT(t.value) AS tagValues WHERE ALL(v IN tagValues WHERE v IN $tagList) RETURN e;
此外,如果一个事件很少有那么多标签,这个较长的查询实际上可能会更快(通过在实际查看标签之前进行度数检查):
MATCH (e:Event) WHERE SIZE((e)-[:IS_TAGGED_BY]->()) >= SIZE($tagList) MATCH (e)-[:IS_TAGGED_BY]->(t:EventTag) WITH e, COLLECT(t.value) AS tagValues WHERE ALL(v IN tagValues WHERE v IN $tagList) RETURN e;