Star

[v2] 查询时添加判断和返回自定义字段

功能需求:查询某个用户的关注列表 (显示我是否已关注)

如果仅仅是要返回关注用户信息,这样的查询很容易实现:

GO FROM "145171858868801536" OVER follows YIELD follows._dst AS id | \
FETCH PROP ON User $-.id YIELD \
  User.name AS name, \
  User.username AS username;

(这里有个小问题,这里返回的id是VertexID,我不知道怎么重命名为id)。

但从业务上来讲,当我查看某个用户的关注列表时,我希望能够看到我(登录用户)是否已关注了这些用户 (可参考微博、推特)。

所以返回的数据中应该要有一个 following 的字段,用于前端显示我是否已关注该用户。

期待返回的数据示例:

[{
  id: "155171858868801536",
  name: "熊猫",
  username: "xiongmao",
  following: true  // 表示登录用户(我)已关注这个 "熊猫" 用户
}]

但这个following字段不是存储在数据库里的,而是查询的时候根据登录用户id去动态判断,然后额外添加的。

假设目标用户是: “145171858868801536” ,登录用户(我)是: “165171858868801539”。

我该怎么写这个查询 ?

1、follows._dst AS id
这里就重命名为id了

2、参考 https://docs.nebula-graph.com.cn/manual-CN/2.query-language/4.statement-syntax/2.data-query-and-manipulation-statements/yield-syntax/
里面有yield 的用法,里面可以加上where 的条件进行过滤

@tom-chensf @yee

不是这个地方,是下面的fetch… yield …

上面语句的查询结果是这样子的:

+----------------------+----------+-------------+
| VertexID             | name    | username    |
+----------------------+----------+-------------+
| "16517185882"  | "熊猫"   | "xiongmao" |
+----------------------+----------+-------------+

它默认返回的id名称是VertexID,我想要重命名为id,而不是返回VertexID。

于是我用$-.id AS id$-.VertexID AS id$-._dst AS idfollows._dst AS id等等都试过了,都会报错,如下:

GO FROM "145171858868801536" OVER follows YIELD follows._dst AS id | \
FETCH PROP ON User $-.id YIELD \
  $-.id AS id, \    // 这里会报错,换成其他写法也报错
  User.name AS name, \
  User.username AS username;

// SemanticError: Unsupported input/variable property expression in yield.

可以根据上面的语句案例直接写个完整的查询语句吗 ?

官方文档非常简陋,看了也没用。yield我看了的,但还是不知道怎么写。

where只是添加过滤条件,但following不只是过滤,它要根据查询的User和登录用户的id,去查找有没有
<登录用户 -> User> 这样的一条边,如果有则在User查询结果中添加following: true字段,没有则添加 following: false

简单归纳就是三步:
1,查询关注列表 [User]
2,列表的每一项(User)需要查询是否有 <登录用户 -> User> 这个边
3,根据2的结果,给User添加following字段

重命名 vertexID 的方式目前可以这样:

GO FROM "145171858868801536" OVER follows YIELD follows._dst AS id | \
FETCH PROP ON User $-.id YIELD \
  User.name AS name, \
  User.username AS username | \
YIELD $-.VertexID AS id, $-.name AS name, $-.username AS username;

对于问题 2 的查询可以如下实现:

GO FROM “145171858868801536” OVER follows YIELD follows._dst AS target_user | \
GO FROM $-.target_user OVER follows REVERSELY \
YIELD $-.target_user AS target_user, \
follows._dst == “165171858868801539” AS following
4赞

@yee 非常感谢!

这样的确可以。 :clap:

还有更简便的方式吗 ?或者后期会改善吗 ?

为了重命名一个id要写两遍YIELD,字段少点倒没什么,但有时候几十个字段,写下来就很糟糕了。而且这个肯定要命名为id的。

为什么不直接默认就是 id 呢 ?返回VertexID感觉怪怪,实际开发中大都数人都不会用这样的名字,而是用id,所以即使返回VertexID给我们,最终还是要改成id的。

希望默认返回名称为id ,其他的语句也一样,尽量契合实际的开发需要。

这个很棒了,可以实现我的需求。 :+1:

这里有个小问题,后面我要返回用户信息的,包含following字段, 所以我改了下,但是报错了:

GO FROM "145171858868801536" OVER follows YIELD follows._dst AS target_user | \
GO FROM $-.target_user OVER follows REVERSELY \
YIELD $-.target_user AS target_user, \
follows._dst == "165171858868801539" AS following | \
FETCH PROP ON User $-.target_user YIELD \
  $-.following AS following, \  // 这里报错,去掉这个一切正常
  User.name AS name, \
  User.username AS username;

我不知道是不是写法有问题,报错信息如下:

SemanticError: Unsupported input/variable property expression in yield

目前 fetch 确实不能 yield 输入的字段,这里需要跟 @jude-zhu 提需求评审了

如果不能的话,那这里把following判断出来也没用,根本用不了,我这功能实现不了。

fetch不行的话,match语句可以吗?

@jude-zhu 如果都不行,希望能够添加这个功能 , 这种场景也是很常见的。

后面又想了下,上面的那个语句有点问题,现修正如下:

GO FROM “145171858868801536” OVER follows YIELD follows._dst AS target_user | \
GO FROM $-.target_user OVER follows REVERSELY \
YIELD $-.target_user AS target_user, \
follows._dst == “165171858868801539” AS following | \
GROUPBY $-.target_user, BIT_OR($-.following) AS following

opencypher 的 match 语句肯定可以支持的,但是 2.0 的 match 还在完善中,2.0 beta 还不能使用,最后的语句类似于:

MATCH (v)-[:follow]->(target), p=(target)<-[:follow]-(me)
WHERE id(v) == "145171858868801536" AND id(me) == "165171858868801539" 
RETURN target.name AS name, target.username AS username, id(target) AS id, exists(p) AS following

我刚刚试了下,报了个错:

SyntaxError: syntax error near `GROUPBY'

也就是说2.0正式版支持这样用是吗 ? 这样的话那我就再等等,这个功能暂且放一放。

修正如下: :sweat_smile:

GO FROM “145171858868801536” OVER follows YIELD follows._dst AS target_user | \
GO FROM $-.target_user OVER follows REVERSELY \
YIELD $-.target_user AS target_user, \
CASE follows._dst == “165171858868801539” WHEN true THEN 1 ELSE 0 END AS following | \
GROUPBY $-.target_user YIELD $-.target_user AS target_user, BIT_OR($-.following) AS following

还是报一样的错 :grinning:

我感觉nGQL好难用,问题一堆堆,还不如opencypher,期待尽快兼容opencypher :muscle:

这是我本地的例子,你可以对照一下:

(root@nebula) [nba]> go from 'Tim Duncan' over like yield like._dst as id | go from $-.id over like reversely yield $-.id as dst, case (like._dst == 'LeBron James') when true then 1 else 0 end as following | group by $-.dst yield $-.dst AS target,  BIT_OR($-.following) as following
+-----------------+-----------+
| target          | following |
+-----------------+-----------+
| "Tony Parker"   | 0         |
+-----------------+-----------+
| "Manu Ginobili" | 0         |
+-----------------+-----------+
Got 2 rows (time spent 8795/9393 us)

Thu, 03 Dec 2020 12:03:44 CST

opencypher 的 MATCH 兼容我们正在做,里面的 feature 挺多,需要点时间,请再耐心等一下。

3赞

现在可以 :+1: 。我知道问题在哪里了,前面的语句,应该是GROUP BY ,却写成了GROUPBY,所以报错了。

但是后面还是没法用fetch查询属性添加following字段,还是没能实现需求…

好的,我是准备等2.0正式版上生产的,但不知道2.0正式版会兼容到什么程度,能否都满足我们的需求。就比如上面的问题,现在就没法满足,做不了。 :expressionless:

目前我们正在做 openCypher TCK 测试框架的开发,后期会把官方的 tck 中的 feature 迁移过来,到时就可以衡量兼容程度了。

后期也欢迎你们给 Nebula Graph 提 feature 测试用例!!

2赞

好的。2.0正式版大概还有多久发布? 预估时间,我好评估下,现在的版本很多问题,一些功能实现不了。我想等2.0正式版发布了再做,不知道还要等多久?

计划是这月底会再有个版本,GA 应该要再往后排一点

有点久。。。那我再等等吧 :expressionless:

1赞

浙ICP备20010487号