使用minus取差集后,如何获取dst的src信息?

需求是:取我关注的关注,过滤掉我已关注的人,然后需要知道我关注的谁关注了他。

所以会用到 minus 取差集,取差集之后,该如何获取dst的src信息呢?

下面是测试的数据:

获取我的二度关注 和 获取我的一度关注,执行结果如下,可以看到都包含一个10000001的点

(user@nebula) [friend]> go 2 step from 33630944 OVER follow yield distinct follow._dst as dst|order by dst asc|limit 5
============
| dst      |
============
| 10000001 |
------------
| 10000005 |
------------
| 10011385 |
------------
| 10036270 |
------------
| 10079598 |
------------
Got 5 rows (Time spent: 14.338/63.063 ms)

Mon Jan 18 09:55:31 2021

(user@nebula) [friend]> go from 33630944 over follow yield distinct follow._dst as dst|order by dst asc|limit 5
============
| dst      |
============
| 10000001 |
------------
| 10019476 |
------------
| 10044807 |
------------
| 10058555 |
------------
| 10062883 |
------------
Got 5 rows (Time spent: 3.153/46.851 ms)

Mon Jan 18 09:55:53 2021

使用 minus 取差集可以过滤掉10000001这个点,如下

(user@nebula) [friend]> (go 2 STEPS from 33630944 OVER follow where follow._dst!=33630944 yield distinct follow._dst as dst  minus go from 33630944 OVER follow yield follow._dst as dst) | order by dst asc | limit 5 
============
| dst      |
============
| 10000005 |
------------
| 10011385 |
------------
| 10036270 |
------------
| 10079598 |
------------
| 10079979 |
------------
Got 5 rows (Time spent: 84.311/128.351 ms)

Mon Jan 18 09:58:42 2021

但是如果在查询结果上加上 follow._src 信息,minus会不起作用,是因为会把 dst 和 src加在一起来取了差集

(user@nebula) [friend]> (go 2 STEPS from 33630944 OVER follow where follow._dst!=33630944 yield distinct follow._dst as dst,follow._src as src  minus go from 33630944 OVER follow yield follow._dst as dst,follow._src as src) | order by dst asc | limit 5
=======================
| dst      | src      |
=======================
| 10000001 | 62100520 |
-----------------------
| 10000001 | 76764760 |
-----------------------
| 10000001 | 47633975 |
-----------------------
| 10000005 | 47633975 |
-----------------------
| 10011385 | 76764760 |
-----------------------
Got 5 rows (Time spent: 83.475/128.034 ms)

所以想请教下:使用minus取差集后,该如何获取dst的src信息?

做社交应用中推荐用户的需求,不论什么规则,基本都需要用minus做过滤,比如过滤掉我的好友,过滤掉我关注的人等等,最后的结果dst也要知道src,所以如果现在1.x版本不支持,希望新发布的2.0版本能支持下。

不能利用取差集以后,利用dst,作为源,查反向边获取src么?

利用dst作为源来查反向边,一个dst有N个反向边,怎么能确定是从哪个src查过来的啊

嗯,我重新看了你的需求,应该类似之前提到的 "我的朋友的朋友不是我的朋友问题”,这里你好像也有提到:怎么样获取这些二度关注来自谁的关注呢? follow._src 好像不能与distinct 和 MINUS同时使用 - #19 by yee

我跟同事确认了,目前我们确实不支持直接查出来,我会把你这个需求在内部反馈,有消息会在这里跟进:handshake:

更新下进度,研发正在开发这块的功能。

好的,谢谢,希望新的版本能尽快提供,:)

1 个赞

你好,请问这个需求现在进展怎么样呀,新的版本支持了么,:)

需求还在待开发阶段,有新的进展我来更新下帖子哈

非常抱歉 Mayer,才看到,您看看Match 能满足您的需求不?

MATCH path = (origin:player {name:"LaMarcus Aldridge"})-[:follow]-(f:player)-[:follow]-(fof:player) \
WHERE NOT(fof == origin or fof == f) \
RETURN DISTINCT fof.name AS new_Friends_of_Friends, f.name AS new_FoF_followed_by

两列分别是新两跳好友和被哪个好友follow


(root@nebula) [basketballplayer]> MATCH path = (origin:player {name:"LaMarcus Aldridge"})-[:follow]-(f:player)-[:follow]-(fof:player) \
                               -> WHERE NOT(fof == origin or fof == f) \
                               -> RETURN DISTINCT fof.name AS new_Friends_of_Friends, f.name AS new_FoF_followed_by
+------------------------+---------------------+
| new_Friends_of_Friends | new_FoF_followed_by |
+------------------------+---------------------+
| "Tim Duncan"           | "Tony Parker"       |
+------------------------+---------------------+
| "Manu Ginobili"        | "Tony Parker"       |
+------------------------+---------------------+
| "Tracy McGrady"        | "Rudy Gay"          |
+------------------------+---------------------+
| "Dejounte Murray"      | "Tony Parker"       |
+------------------------+---------------------+
| "Marco Belinelli"      | "Tony Parker"       |
+------------------------+---------------------+
| "Boris Diaw"           | "Tony Parker"       |
+------------------------+---------------------+
Got 6 rows (time spent 316915/329628 us)

Wed, 20 Oct 2021 14:20:32 CST

你好,快一年了,这个获得dst的src需求现在怎么样了呢

现在的 master,或者马上的 3.1.0 支持 WHERE 里的 路径 PATTERN 表达,可以这么写了

match (n:player)-[:follow]->(x:player)-[:follow]->(m:player) \
where id(n)=="player100" and not (n:player)-[:follow]->(m:player) \
return m,x

比如:

(root@nebula) [basketballplayer]> 
match (n:player)-[:follow]->(x:player)-[:follow]->(m:player) \
    where id(n)=="player100” \
    and not (n:player)-[:follow]->(m:player) \
return m as new_fof, collect(x) as common_friend

+----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| new_fof                                            | common_friend                                                                                                                                                                                                                |
+----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"}) | [("player102" :player{age: 33, name: "LaMarcus Aldridge"}), ("player125" :player{age: 41, name: "Manu Ginobili"}), ("player101" :player{age: 36, name: "Tony Parker"}), ("player101" :player{age: 36, name: "Tony Parker"})] |
+----------------------------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Got 1 rows (time spent 10929/91577 us)

Fri, 22 Apr 2022 10:06:02 CST

PS. 应该再加一个条件 and id(m) != id(n),过滤掉自己,这里的结果因为数据集的原因,加上 and id(m) != id(n) 其实就没有 new friend of friend 了,这就是一个例子哈,欢迎试试、探索哈。

update:这个101的情况下有数据了。

(root@nebula) [basketballplayer]> match (n:player)-[:follow]->(x:player)-[:follow]->(m:player) \
    where id(n)=="player101" and \
    not (n:player)-[:follow]->(m:player) and \
    id(m) != id(n) \
return m as new_fof,collect(x) as common_friend

+--------------------------------------------------+------------------------------------------------------+
| new_fof                                          | common_friend                                        |
+--------------------------------------------------+------------------------------------------------------+
| ("player103" :player{age: 32, name: "Rudy Gay"}) | [("player100" :player{age: 42, name: "Tim Duncan"})] |
+--------------------------------------------------+------------------------------------------------------+
Got 1 rows (time spent 11080/110073 us)

1 个赞

数据量比较大时,match的效率太慢了,有go语法实现该目标的例子吗