ent 基本使用四 图遍历查询
接上文,我们已经创建了基本的关系以及表实体,以下是通过图方式的查询
参考关系图

代码处理
- 创建图数据
func CreateGraph(ctx context.Context, client *ent.Client) error {
// first, create the users.
a8m, err := client.User.
Create().
SetAge(30).
SetName("Ariel").
Save(ctx)
if err != nil {
return err
}
neta, err := client.User.
Create().
SetAge(28).
SetName("Neta").
Save(ctx)
if err != nil {
return err
}
// then, create the cars, and attach them to the users in the creation.
_, err = client.Car.
Create().
SetModel("Tesla").
SetRegisteredAt(time.Now()). // ignore the time in the graph.
SetOwner(a8m). // attach this graph to Ariel.
Save(ctx)
if err != nil {
return err
}
_, err = client.Car.
Create().
SetModel("Mazda").
SetRegisteredAt(time.Now()). // ignore the time in the graph.
SetOwner(a8m). // attach this graph to Ariel.
Save(ctx)
if err != nil {
return err
}
_, err = client.Car.
Create().
SetModel("Ford").
SetRegisteredAt(time.Now()). // ignore the time in the graph.
SetOwner(neta). // attach this graph to Neta.
Save(ctx)
if err != nil {
return err
}
// create the groups, and add their users in the creation.
_, err = client.Group.
Create().
SetName("GitLab").
AddUsers(neta, a8m).
Save(ctx)
if err != nil {
return err
}
_, err = client.Group.
Create().
SetName("GitHub").
AddUsers(a8m).
Save(ctx)
if err != nil {
return err
}
log.Println("The graph was created successfully")
return nil
}
- 查询组名称为github 的用户以及汽车
func QueryGithub(ctx context.Context, client *ent.Client) error {
cars, err := client.Group.
Query().
Where(group.Name("GitHub")). // (Group(Name=GitHub),)
QueryUsers(). // (User(Name=Ariel, Age=30),)
QueryCars(). // (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
All(ctx)
if err != nil {
return fmt.Errorf("failed getting cars: %v", err)
}
log.Println("cars returned:", cars)
// Output: (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Mazda, RegisteredAt=<Time>),)
return nil
}
- 查询用户
Ariel的车
func QueryArielCars(ctx context.Context, client *ent.Client) error {
// Get "Ariel" from previous steps.
a8m := client.User.
Query().
Where(
user.HasCars(),
user.Name("Ariel"),
).
OnlyX(ctx)
cars, err := a8m. // Get the groups, that a8m is connected to:
QueryGroups(). // (Group(Name=GitHub), Group(Name=GitLab),)
QueryUsers(). // (User(Name=Ariel, Age=30), User(Name=Neta, Age=28),)
QueryCars(). //
Where( //
car.Not( // Get Neta and Ariel cars, but filter out
car.ModelEQ("Mazda"), // those who named "Mazda"
), //
). //
All(ctx)
if err != nil {
return fmt.Errorf("failed getting cars: %v", err)
}
log.Println("cars returned:", cars)
// Output: (Car(Model=Tesla, RegisteredAt=<Time>), Car(Model=Ford, RegisteredAt=<Time>),)
return nil
}
- 查询包含用户的组
func QueryGroupWithUsers(ctx context.Context, client *ent.Client) error {
groups, err := client.Group.
Query().
Where(group.HasUsers()).
All(ctx)
if err != nil {
return fmt.Errorf("failed getting groups: %v", err)
}
log.Println("groups returned:", groups)
// Output: (Group(Name=GitHub), Group(Name=GitLab),)
return nil
}
查询sql
为了查看生成的sql,我启用了慢查询处理
set global long_query_time=0;
set global slow_query_log=1;
- 生成的sql
以下是一个查询的sql,我进行了格式化
SELECT
DISTINCT `cars`.`id`,
`cars`.`model`,
`cars`.`registered_at`
FROM
`cars`
JOIN (
SELECT
`users`.`id`
FROM
`users`
JOIN (
SELECT
`group_users`.`user_id`
FROM
`group_users`
JOIN (
SELECT
`groups`.`id`
FROM
`groups`
JOIN (
SELECT
`group_users`.`group_id`
FROM
`group_users`
JOIN `users` AS `t0` ON `group_users`.`user_id` = `t0`.`id`
WHERE
`t0`.`id` = 10
) AS `t1` ON `groups`.`id` = `t1`.`group_id`
) AS `t1` ON `group_users`.`group_id` = `t1`.`id`
) AS `t1` ON `users`.`id` = `t1`.`user_id`
) AS `t1` ON `cars`.`owner_id` = `t1`.`id`
WHERE
NOT (`cars`.`model` = 'Mazda');
查看查询计划
EXPLAIN SELECT DISTINCT `cars`.`id`, `cars`.`model`, `cars`.`registered_at` FROM `cars` JOIN (SELECT `users`.`id` FROM `users` JOIN (SELECT `group_users`.`user_id` FROM `group_users` JOIN (SELECT `groups`.`id` FROM `groups` JOIN (SELECT `group_users`.`group_id` FROM `group_users` JOIN `users` AS `t0` ON `group_users`.`user_id` = `t0`.`id` WHERE `t0`.`id` = 10) AS `t1` ON `groups`.`id` = `t1`.`group_id`) AS `t1` ON `group_users`.`group_id` = `t1`.`id`) AS `t1` ON `users`.`id` = `t1`.`user_id`) AS `t1` ON `cars`.`owner_id` = `t1`.`id` WHERE NOT (`cars`.`model` = 'Mazda');

说明:
从上边可以看出通过索引进行了优化,还是比较高效的
参考资料
https://entgo.io/docs/getting-started/
https://github.com/rongfengliang/ent-demo
ent 基本使用四 图遍历查询的更多相关文章
- OO第四单元总结——查询UML类图 暨 OO课程总结
一.本单元两次作业的架构设计总结 作业一.UML类图查询 1. 统计信息图 2. 复杂度分析 基本复杂度(Essential Complexity (ev(G)).模块设计复杂度(Module Des ...
- CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏
CASE函数 作用: 可以将查询结果集的某一列的字段值进行替换 它可以生成一个新列 相当于switch...case和 if..else 使用语法: case 表达式/字段 when 值 then ...
- 20162327WJH实验四——图的实现与应用
20162327WJH实验四--图的实现与应用 实 验 报 告 课程:程序设计与数据结构 班级: 1623 姓名: 王旌含 学号:20162327 成绩: 指导教师:娄嘉鹏 王志强 实验日期:11月2 ...
- Gremlin:图遍历语言
Gremlin简介 Gremlin是Apache TinkerPop 框架下的图遍历语言.Gremlin是一种函数式数据流语言,可以使得用户使用简洁的方式表述复杂的属性图(property graph ...
- 《数据结构与算法(C语言版)》严蔚敏 | 第五章 建立二叉树,并完成三/四种遍历算法
PS:所有的代码示例使用的都是这个图 2019-10-29 利用p126的算法5.3建立二叉树,并完成三种遍历算法 中序 后序 先序 #include<iostream> #include ...
- java map的四种遍历
四种遍历: public static void main(String[] args) { Map<String, String> map = new HashMap<String ...
- lua中for循环的四种遍历方式
lua中for的四种遍历方式区别 table.maxn 取最大的整数key #table 从1开始的顺序整数最大值,如1,2,3,6 #table == 3 key,value pairs 取每一 ...
- MYSQL的全表扫描,主键索引(聚集索引、第一索引),非主键索引(非聚集索引、第二索引),覆盖索引四种不同查询的分析
文章出处:http://inter12.iteye.com/blog/1430144 MYSQL的全表扫描,主键索引(聚集索引.第一索引),非主键索引(非聚集索引.第二索引),覆盖索引四种不同查询的分 ...
- Map的四种遍历
//Map的四种遍历方法 public static void main(String[] args) { Map<String, String> map = new HashMap< ...
随机推荐
- golang --rune
rune 是int32的别名类型,专用于存储Unicode编码的单个字符 我们可以用5种方式来表示一个rune字面量: 该rune字面量所对应的字符,如'a'必须是Unicode编码规范所支持的 使用 ...
- MOOC 编译原理笔记(一):编译原理概述以及程序设计语言的定义
编译原理概述 什么是编译程序 编译程序指:把某一种高级语言程序等价地转换成另一张低级语言程序(如汇编语言或机器代码)的程序. 高级语言程序-翻译->机器语言程序-运行->结果. 其中编译程 ...
- 新版GRANAFA K8S插件 K8S NODE 图表不显示问题解决方法
原文:https://www.wchao.site/archives/granafa-k8s 其他参考:https://blog.csdn.net/bbwangj/article/details/82 ...
- webpack 入门和常用插件的使用
常用配置参数 module.exports = { context: path.resolve(__dirname, '../'), entry: { app: './src/main.js' }, ...
- CRM BP函数
REPORT ZCRM_BP_TEST. """""""""""""& ...
- python中生成JWK(json web token)
#需要安装pyjwt import jwt import time # 使用 sanic 作为restful api 框架 def create_token(request): grant_type ...
- FFmpeg Windows下安装与测试
FFmpeg 简介 FFmpeg的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward",FFmpeg是一套可以用来记录.转换数字音频.视 ...
- Linux多网卡绑定(bond)及网络组(team)
Linux多网卡绑定(bond)及网络组(team) 很多时候,由于生产环境业务的特殊需求,我们需要对服务器的物理网卡实施特殊的配置,从而来满足不同业务场景下对服务器网络的特殊性要求.如高并发的网 ...
- Introduction to Linux Threads
Introduction to Linux Threads A thread of execution is often regarded as the smallest unit of proces ...
- JVM存储位置分配——java中局部变量、实例变量和静态变量在方法区、栈内存、堆内存中的分配
Java中的变量根据不同的标准可以分为两类,以其引用的数据类型的不同来划分可分为“原始数据类型变量和引用数据类型变量”,以其作用范围的不同来区分可分为“局部变量,实例变量和静态变量”. 根据“Java ...