Neo4j/Cypher:如果满足某些条件,则创建关系 [英] Neo4j / Cypher: create relationship if certain condition is met

查看:908
本文介绍了Neo4j/Cypher:如果满足某些条件,则创建关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在图形数据库中执行求和运算:比较两个节点,计算一个图形以表示图形某些区域的相似程度,如果该图形足够大,我想在图形之间创建关系节点.

I am doing a sum operation in my graph DB: I compare a couple of nodes, calculate a figure to represent how similar certain regions of the graph are and if that figure is big enough, I want to create a relationship between the nodes.

我有一个查询可以完成所有的工作,除了检查图形是否足够大之外.它目前还创建了相似度得分为0的相似度关系-我不希望如此.

I've got a query which does all that, except for the check if the figure is big enough; it currently also creates similarity relationships whose similarity score is 0 - and I don't want that.

我的完整密码查询有些冗长,因此在本文中已对其进行了简化.因此,恐怕我无法在neo4j控制台中提供示例图数据库.我的图包含Center个节点,这些节点周围有Affinity个节点和Searched个节点.如果2个Center节点具有相似的Affinity或Searched节点,则Center节点应建立关系.

My full cypher query is somewhat longish, so I've simplified it for this post. Therefore I'm afraid I cannot provide a sample graph db in the neo4j console. My graph contains Center nodes, which have Affinity nodes and Searched nodes around them. If 2 Center nodes have similar Affinity or Searched nodes, the Center nodes shall get a relationship.

这是带有注释的简化语句:

Here's the simplified statement with annotations:

MATCH (a:Center), (x:Center)
WHERE id(a) <> id(x)
OPTIONAL MATCH a-->(aff1:Affinity), x-->(aff2:Affinity)
WHERE aff1.affinityReference=aff2.affinityReference     // if the Affinity nodes have the same reference, then their Center nodes are similar
OPTIONAL MATCH a-->(search1:Search), x-->(search2:Search)
WHERE search1.searchTerm = search2.searchTerm   // if the Search nodes have the same searchTerm, then their Center nodes are similar
WITH a, x, 
SUM (CASE WHEN aff2.relative_weight IS NULL THEN 0 ELSE (aff2.relative_weight * 5) END) AS AffinityScore, // Affinity nodes have a relative weight, which shall be used in the similarity calculation.
(count(search2) * 5) AS SearchScore   // matching Search nodes shall just be counted and multiplied with 5.

OPTIONAL MATCH x-[r1:IS_SIMILAR_TO]->()  // Delete all similarity relationships for x
WITH a,x,r1,AffinityScore, SearchScore, (AffinityScore+SearchScore) AS TotalScore

DELETE r1   // delete relationship if it exists...
MERGE      // ... and create it anew.
  x-[:IS_SIMILAR_TO {
  SimilarityScore:Total,
  AffinityScore:AffinityScore,
 SearchScore:SearchScore
 }]->a

RETURN a, x, AffintyScore, SearchScore, TotalScore 
ORDER BY TotalScore DESC

我曾尝试在不同地方引入CASE语句,但显然从来没有在正确的地方提出过.应该去哪里?

I've tried introducing a CASE statement in various places, but apparently never in the right one. Where should it go?

感谢您的帮助!

推荐答案

执行条件变异操作有一个技巧:条件为true时,使用CASE语句返回长度为1的列表,否则为空列表.然后FORACH遍历该数组以执行CREATEMERGE

There is a trick to do a conditional mutating operation: use a CASE statement to return a list of length 1 when the condition is true, otherwise an empty list. Afterwards a FORACH to iterate over that array to do the CREATE or MERGE

...
WITH a, x, AffintyScore, SearchScore, TotalScore, Total, 
  CASE AffinityScore WHEN 0 THEN [] ELSE [1] END as array
FOREACH (x in array | 
   MERGE
   x-[:IS_SIMILAR_TO {
   SimilarityScore:Total,
   AffinityScore:AffinityScore,
   SearchScore:SearchScore
   }]->a 
)
RETURN a, x, AffintyScore, SearchScore, TotalScore 
ORDER BY TotalScore DESC

这篇关于Neo4j/Cypher:如果满足某些条件,则创建关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆