SHOW QUERY,这里有社区用户常用的 nGQL 查询语句

目前活动已经结束,:thinking: 大家依旧在本帖留下你的常用查询语句。如果你要通过本帖来找寻某个查询场景的具体语句,可以参考下面的方式:

  1. 确定检索词:这个场景涉及到 tag 还是 edge,以此为检索关键词进行检索;或者是直接检索你的需求关键词,例如:删除悬挂边(由于每个人表达方式不同,这种检索词可能会搜不到其实本来存在的查询语句)
  2. 检索本帖:command + f(macOS 系统)或是 ctrl + f(Windows 系统),输入检索词,进行检索。
被折叠的原活动贴

早几个月之前 @helloworld 曾在 根据属性值删除对应的边数据 - #4,来自 helloworld 帖子中提过“针对具体的查询场景编写语句时,有时没有思路下手,能不能给出些学习的建议” 的需求。而我也在帖子里说过,抽空会整理下论坛相关的 nGQL 语句。自然,这不是一个大约在冬季的约定。

经过一段时间整理,现在我整理了近半年的 nGQL 语句。整理的过程中,我冒出个点子(绝壁不是偷懒),既然这些查询语句以后也是要和大家分享的,不如索性搞个活动,大家一起分享下日常的 nGQL。

当然,为了避免你晒完 nGQL,就要和 HR 聊职业规划,你的 nGQL 最好脱敏下。相对应的,为了大家好理解,如果你的语言时根据特定场景的话,最好对 schema 也解释一下,方便阅读查询语句的小伙伴理解语句作用。

现在,是时候来说下 SHOW QUERY 怎么玩了。非常简单,在本帖下方贴出你的常用 nGQL,或者你写过的非常复杂且能跑的 nGQL,一切你觉得值得分享的 nGQL 语句都可以 SHOW 下。

活动时间

即日 - 2023.05.26,在本帖下方贴出你的 nGQL 查询语句。贴语句的格式参考:

  • 场景描述:说下这个语句的作用
  • 查询语句:具体的语句是什么
  • 适用版本:你的语句运行在哪个 NebulaGraph 内核版本上

自然,还有其他格式:

  • 注意事项:是否需要创建索引
  • 语句说明:解释下这个语句的 tag 属性之类的解释性语句

特殊说明

可以分享常用的 nGQL 语句,不一定是你自己写的,比如:show stats 我用来统计整个图的数据量;

这边有礼

  • 不可背锅钥匙扣:分享的 nGQL 之前未有人分享的小伙伴可以获得 1 个钥匙扣,可重复获得,单用户最多获得 3 个钥匙扣
  • 大展红兔吉祥物:分享的 nGQL 能获得 3 个 :heart: 的小伙伴可以获得 1 只兔年吉祥物,可重复获得,单用户最多获得 2 只吉祥物
  • ¥ 100 星巴克礼卡:根据用户的喜欢程度(:heart: 个数),前三名的小伙伴可以获得一张星巴克礼卡;

image

最后,上文说过本活动本来是在整理论坛 nGQL 之余,顺便收集下大家常用、能用、好用的 nGQL。因此,即便在活动结束之后,论坛有明确用户的 nGQL 语句也会持续更新在本帖中。

希望,在大家一起的努力下,我们有个 nGQL 速查表,一查大家的语句编写问题就没啦~~

1 个赞

场景:查询两点路径中通过某一顶点的路径
语句:

FIND ALL PATH FROM "player100" TO "player101" OVER * BIDIRECT YIELD path as p |
    YIELD $-.p WHERE "player104" IN [n in nodes($-.p)| id(n)]

适用版本: v2.6, v3.x
注释:这里重点在于列表展开的表达
出处:https://gist.github.com/wey-gu/f41e8a5651d95506b37bee6a8b5a1b8c

3 个赞

场景:查询出很多刚导入的图给 studio/explorer 进行可视化,支持 3.0 的无索引场景
语句:

MATCH (n) WITH n LIMIT 1000
OPTIONAL MATCH p=(n)--()
RETURN p, n

或者

MATCH (n) WITH n LIMIT 1000
OPTIONAL MATCH (n)-[e]-(m)
RETURN n,e,m

适用版本: v3.x
注释:这里重点在于在 3.0~3.4 中,不允许无索引的数据全扫描的情况下,利用 LIMIT 去扫数据
出处:https://gist.github.com/wey-gu/f41e8a5651d95506b37bee6a8b5a1b8c

1 个赞

场景:如果想要通过描述多跳的边的过滤条件,比如-[e:follow*2]->,这时候变量 e 不再是单条边时候的数据类型了,而是一列边组成的列表,例如: 以下语句可以运行但是没有返回数据,因为e是一个列表,没有.degree的属性。
错误的表达

这里 e 没有 .degree,所以条件一定不满足

MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE e.degree > 1 \
        RETURN DISTINCT v2 AS Friends;

语句:

-- 限制所有 follow 边
MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE ALL(e_ in e WHERE e_.degree > 0) \
        RETURN DISTINCT v2 AS Friends;

或者放在花括号里

MATCH (n:player)-[e:follow*3{degree:95}]-(v)
    RETURN n
-- 限制第一个 follow
MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
        WHERE e[0].degree > 98 \
        RETURN DISTINCT v2 AS Friends;

适用版本: v2, v3
注释:边变量可变长度时候是一个 list
出处:https://gist.github.com/wey-gu/f41e8a5651d95506b37bee6a8b5a1b8c

1 个赞

由于 NebulaGraph 的每个版本的子句使用会存在出入,以下语句不代表适用于所有的 NebulaGraph 发行版;此外,由于个别语句对特定场景生效,不代表它具有通用性!

  • 语句 1
    • 场景:统计某个节点下游所有节点的数量
    • 具体语句:match (v:player)-[e*1…]->(v2) where id(v)==“player100” return count(distinct v2)
    • 适用版本:v3.2.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/12441
  • 语句 2
    • 场景:统计某个节点下游指定 Tag 下所有节点的数量
    • 具体语句:match (v:player)-[e*1..]->(v2:player) where id(v)=="player100" return count(distinct v2)
    • 适用版本:v3.2.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/12441
  • 语句 3
  • 语句 4
  • 语句 5
    • 场景:悬挂边的黑点批量删除 / 可用来删除无 tag 的点
    • 具体语句:已知边类型且创建边索引的情况下,先执行 (((lookup on like yield like._src as srcId |go from $-.srcId over like yield id($$) as vid) minus (lookup on like yield like._src as srcId | go from $-.srcId over like yield id($$) as dstId | fetch prop on * $-.dstId yield id(vertex) as vid)) | go from $-.vid over * bidirect yield distinct id($^) as srcId, id($$) as dstId) | delete edge like $-.srcId->$-.dstId 再执行 (((lookup on like yield like._src as srcId |go from $-.srcId over like yield id($$) as vid) minus (lookup on like yield like._src as srcId | go from $-.srcId over like yield id($$) as dstId | fetch prop on * $-.dstId yield id(vertex) as vid)) | go from $-.vid over * bidirect yield distinct id($^) as srcId, id($$) as dstId) | delete edge like $-.dstId->$-.srcId
    • 适用版本:v3.0.2
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/11905/4
  • 语句 6
    • 场景:子图对节点/边的类型或属性过滤
    • 具体语句:get subgraph 2 steps from "Tim Duncan" both serve yield vertices as a | unwind $-.a as t | yield $-.t where "player" in tags($-.t)
    • 适用版本:v3.4.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/12108/5
  • 语句 7
    • 场景:统计图中每一个节点的二度出度值
    • 具体语句 1:第一种方式:MATCH (v:A) RETURN size((v)-->()) AS out_degree1, size((v)-->()-->()) AS out_degree2
    • 具体语句 2:第二种方式:MATCH (v:A) WHERE size((v)-->()-->()) > size((v)-->()) RETURN v
    • 适用版本:v3.3.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/12067/5
  • 语句 8
    • 场景:输出结果为边列表时,返回边类型属性
    • 具体语句:match (v:player{name:“Tim Duncan”})-[e*1…2]->(v2) unwind e as edgelist return edgelist
    • 适用版本:v3.3.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/12028
2 个赞
  • 语句 1
    • 场景:如何实现类似的 JOIN 功能
    • 具体语句:试试 match 和多个 optional match
    // 1
    MATCH(v)-[e:person_knows_person*1..3]-(v2) WHERE v.person.firstName == "firstName"
    // 2
    OPTIONAL MATCH (v2)-[e2: person_isLocatedIn_place]-(v3)
    // 3
    OPTIONAL MATCH (v2)-[e3: person_studyAt_organisation]-(v4)
    // 4
    OPTIONAL MATCH (v2)-[e3: person_workAt_organisation]-(v5)
    // 查找国家
    ...
    WITH v2 as personName, v3 as workingPlace, v4 as college, v5 as company
    RETURN personName, workingPlace, college, company, country
    
  • 语句 2
    • 场景:如何筛选出某个 rank 值对应的路径
    • 具体语句:MATCH p=(v)-[e:follow]-(v2) WHERE id(v) == "player10" and rank(e) == 1 RETURN pLIMIT 100
    • 适合版本:v2.5.0
    • 语句出处:https://discuss.nebula-graph.com.cn/t/topic/11726
1 个赞
  • 语句 1
    • 场景:如何进行数据统计,分别用 LOOKUP、MATCH 和 SHOW STATS
    • 具体语句:以统计某条边为例子,记得 MATCH 需要创建索引,如果是导入数据后创建的索引,记得进行 REBUILD INDEX 操作。
    # LOOKUP
    lookup on edge_name yield edge as e | yield count(*)
    # MATCH
    match (m) - [e:edge_name] - (n) return count(e)
    # SHOW STATS 
    看文档:https://docs.nebula-graph.com.cn/3.4.1/3.ngql-guide/7.general-query-statements/6.show/14.show-stats/
    
  • 语句 2
  • 语句 3
    • 场景:根据属性删除对应边
    • 具体语句:
    Lookup on `in_user` where in_user.user_type == 2 yield src(edge) as src, dst(edge) as dst | delete edge `in_user` $-.src->$-.dst
    
  • 语句 4
    • 场景:删除没有边的点
    • 具体语句:
    lookup on player yield id(vertex) as vid  
    minus 
    (lookup on player yield id(vertex) as vid | go 1 step from $-.vid over * bidirect yield distinct id($^) as vid)
    )
    | delete vertex $-.vid
    
1 个赞
  • 语句 1
    • 场景:如何合并两个子图
    • 具体语句:
    get subgraph 5 step from pod in have,belong yield vertices as nodes, edges as relationshiops
    union all
    get subgraph 5 step from pod out have,belong yield vertices as nodes, edges as relationshiops
    
  • 语句 2
    • 场景:自定义排序规则
    • 具体语句:
    MATCH (a)-[e1]->(b)-[e2]->(c)
    WITH e1.cost+e2.cost as cost, c ORDER BY cost
    RETURN c
    
  • 语句 3
    • 场景:一跳,返回这个点的所有连接到的点,然后这个连接到的点, 进行一个分组限制每种类型只返回10个,然后每种类型的10个点进行二跳
    • 具体语句:
    MATCH (a)-[b]->(c) where id(a)="*****"
    WITH labels(c) AS ctype, collect(distinct c)[0..10] AS c_with_same_type
    UNWIND c_with_same_type AS cc
    OPTIONAL MATCH (cc)-[d]->(e) 
    RETURN cc, d, e
    
1 个赞
  • 语句 1
    • 场景:nGQL 中同 SQL 的 Having 类似的操作
    • 具体语句:
    LOOKUP ON ip YIELD id(vertex) as id
          | GO FROM $-.id over activeIn  REVERSELY
          WHERE head(labels($))  == 'equipment'
          YIELD id($) as dst, id($^) as src
          | GO FROM $-.dst over login REVERSELY
          WHERE head(labels($)) == 'account'
          YIELD id($) as dst, id($^) as src
          |GROUP BY $-.src YIELD $-.src as src,count($-.src) as degree
          | YIELD $-.src as src where $-.degree > $p0
          | GO FROM $-.src over login REVERSELY
          YIELD properties($).accountUuid as accountUuid
    
  • 语句 2
    • 场景:根据边的终点,找寻该点下的所有边
    • 具体语句:
    go from "dst ip" over url_ip REVERSELY yield id($) as url 
    | go from $-.url over * yield type(edge) as et, edge as e
    
  • 语句 3
    • 场景:同一类型的边,保留 rank 最大、最小值的边
    • 具体语句:
    match (v1:player)-[e:serve]->(v2:team) 
    with max(rank(e)) as max_rank
    match (v3:player)-[e2:serve]->(v4:team)
    where rank(e2) == max_rank
    return count(e2);
    
2 个赞
  • 语句 1
    • 场景:删除某个 tag 类型点,或者某个类型边
    • 具体语句:
    lookup on A yield id(vertex) as vid | delete vertex $-.vid
    
    lookup on E yield E._src as src,E._dst as dst|delete edge E $-.src->$-.dst
    
  • 语句 2
    • 场景:边属性比较
    • 具体语句:
    MATCH (v:player)-[e:follow]-(v2) 
      WHERE id(v) == 'player100' AND e.degree > 85
    RETURN v2.player.name, e.degree;
    
  • 语句 3
    • 场景:筛选特定出入度的点
    • 具体语句:以出度为 2 为例
    #大于等于 2
    MATCH (:房间)<-[:入住]-(v:人)-[:入住]->(:房间)
    RETURN distinct v
    #大于 2
    MATCH (v:人)-[:入住]->(:房间)
    where size((v)-[:入住]->())>2
    RETURN distinct v
    
  • 语句 4
    • 场景:查询某个 vertex 为终点的路径
    • 具体语句:
    MATCH p=(v)-[*1..10]-(m) 
    where id(v)=="host001" and all( midNode in [n in nodes(p) where id(n)<>id(v)  | n] where "frontPort" not in tags(midNode))
    RETURN p
    
1 个赞
  • 语句 1
    • 场景:找寻某个点出发的某种类型边的终点,两点之前不存在多条同类型边
    • 具体语句:
    MATCH (v)-[e:follow]->(n) where id(v) in ["player101"] 
    WITH id(v) AS vid1, id(n) AS vid2 collect(e) AS edge1 where size(edge1)==1
    RETURN edge1
    
  • 语句 2
    • 场景:找寻环数据,如何查找出图数据库中会形成环的数据
    • 具体语句:
    MATCH p=(v:tag)-[:blood*1..10]->(v)
    RETURN p
    
  • 语句 3
    • 场景:查询指定tag的所有孤点,并删除该点
    • 具体语句:
    ((lookup on table | yield $-.VertexID as id) 
    MINUS 
    (lookup on table | yield $-.VertexID as id | go from $-.id over * BIDIRECT yield $-.id as id)) 
    | delete $-.id
    
1 个赞
  • 语句 1
    • 场景:搜索所有包含某个字符串或字串的点或边
    • 具体语句:
    match (v) with properties(v) as props, keys(properties(v)) as kk, v limit 10000 where [i in kk where props[i] == “Tony Parker”] return v
    
    match ()-[e]->() with e, properties(e) as props, keys(properties(e)) as kk limit 10000 where [i in kk where props[i] == 90] return e
    
  • 语句 2
    • 场景:yield 返回多个标签的所有属性
    • 具体语句:
    fetch prop on * "vertex_id" yield properties(vertex);
    
  • 语句 3
    • 场景:如何筛选没有出边的点
    • 具体语句:
    MATCH p=(v1:company)-[*1..10]->(v2:company)-[:SHList]->(v3:person)
    WHERE id(v1)=="company1"
    RETURN v3.person.name, p
    
  • 语句 4
    • 场景:获取该子图中边缘的点(入度为 0 的点的集合)
    • 具体语句:
    #GO
     GET SUBGRAPH 10 steps FROM "Tim Duncan" IN EdgeType YIELD VERTICES AS nodes | yield $-.nodes[6]
    
    #MATCH
    MATCH (v)<-[:EdgeType*1..10]-(n) 
    WHERE id(v)=="vid" AND NOT (n)<-[:EdgeType]-()
    RETURN n
    
  • 语句 5
    • 场景:两个 MATCH 交并差计算之后如何统计数量
    • 具体语句:
    MATCH (n:player)
    RETURN n.player.name AS name
    UNION
    MATCH (n:team)
    RETURN n.team.name AS name
    
  • 语句 6
    • 场景:如何限制节点扩展的数量
    • 具体语句:
    nebula> GO 3 STEPS FROM "player100" \
          OVER * \
          YIELD properties($).name AS NAME, properties($).age AS Age \
          LIMIT [3,3,3];
    
1 个赞

推荐一个帖子

里面讲述了一些 nGQL 书写的 tips。

1 个赞
  • 语句 1
    • 场景:集合多个查询结果,一次性返回 2 条 nGQL 查询结果
    • 具体语句:
    GO 3  STEPS FROM "ADDRESS_1015" OVER related YIELD 
    case when $^.Staff.STAFF_NAME IS NOT EMPTY and $^.Staff.STAFF_ROLE == "派送人员" then related._src else null end AS dst, 
    case when $.busi_store.BUSI_STORE_NAME IS NOT EMPTY then properties($) else null end AS props;
    
  • 语句 2
    • 场景:获取节点的全部属性,并排序:先一条查出目标节点 ID,再根据目标节点的字段排序,然后取前 10条…
    • 具体语句:
    GO FROM "Tim Duncan" OVER like YIELD like._dst AS dst | FETCH PROP ON * $-.dst YIELD player.age AS age,vertex AS allProperties | ORDER BY $-.age | LIMIT 3 | YIELD $-.allProperties AS allProperties
    
  • 语句 3
    • 场景:查询没有入边只有出边的点
    • 具体语句:
    MATCH (v:table)<–() where not (v:table)–>() RETURN id(v)
    
1 个赞
1 个赞
  • 语句 1
    • 场景:用 GO 做多 tag 的条件筛选
    • 具体语句:
    GO FROM <A>/* 这里需要是id */ over com WHERE $^.acc.time >= "" yield e1._dst AS dst, $^.acc.flgid AS flgid
    | GO FROM $-.dst OVER com REVERSELY WHERE $^.acc.time >= "" AND $^.acc.timeflg==0 AND $-.flgid=$.comtag.flgid /*其他过滤属性同理*/ YIELD $-.src AS A, com._src AS B
    UNION
    
  • 语句 2
    • 场景:GO 语句查询结果将起始点和终点合成一个列表
    • 具体语句(:warning:下面语句的括号记得加上):
    (GO FROM a  OVER H BIDIRECT YIELD src(edge) as src UNION GO FROM  a OVER H BIDIRECT  YIELD dst(edge) as src) | GO FROM $-.src OVER H  YEILD dst(edge)
    
  • 语句 3
    • 场景:查询多个点的共同邻居
    • 具体语句:
    MATCH (v)--(v2) WHERE id(v2)=="player100" RETURN DISTINCT id(v) 
    INTERSECT MATCH (v)--(v2) WHERE id(v2)=="team203" RETURN DISTINCT id(v) 
    INTERSECT MATCH (v)--(v2) WHERE id(v2)=="player101" RETURN DISTINCT id(v)
    
1 个赞

按照权重的最短路径 weighted shortest path:

利用了 relationships()reduce() 进行累加

FIND ALL PATH WITH PROP FROM "player100" TO "player101" OVER follow BIDIRECT 
  YIELD path AS p | 
  YIELD $-.p, reduce(total_weight = 0, r IN relationships($-.p) | total_weight + r.degree) AS total_weight |
  ORDER BY $-.total_weight DESC

ref: Shortest path in directed graph with weights · Issue #4309 · vesoft-inc/nebula · GitHub

1 个赞
  • 语句 1
    • 场景:跳过有特殊标记的子图
    • 具体语句:
    Get Subgraph with prop N steps From 'xxx' OUT edgeType WHERE $$.person.is_skip is EMPTY OR $$.person.is_skip == false YIELD vertices AS nodes, edges AS relationships
    
  • 语句 2
    • 场景:修改 lookup / find path 等返回结果,参考方式——采用管道
    • 具体语句:
    FIND PATH ... | YIELD nodes($-.path) AS ns, relationships($-.path) AS es
    
1 个赞
  • 语句 1
    • 场景:对同类项进行合并,将结果中某个字段值相同的其他结果进行合并;
    • 具体语句:
    MATCH (uu:player)-[e:follow]->(p:player)-[:serve]->(f:team)
      WHERE id(f) == "team204"
      WITH p
    MATCH ()-[e:follow]->(p:player)
    WITH id(p) AS p, e.degree AS degree, count(e) AS count
    RETURN p, collect(degree), collect(count)