断言

字段断言

  • 布尔类型
    • \=, !=
  • 数字类型
    • \=, !=, >, <, >=, <=,
    • IN, NOT IN
  • 时间类型
    • \=, !=, >, <, >=, <=
    • IN, NOT IN
  • 字符类型
    • \=, !=, >, <, >=, <=
    • IN, NOT IN
    • Contains, HasPrefix, HasSuffix
    • ContainsFold, EqualFold (只能用于 SQL 语句)
  • JSON类型:
    • \=, !=
    • \=, !=, >, <, >=, <= on nested values (JSON path).
    • Contains (只能用于包含嵌套的 JSON path 表达式)
    • HasKey, Len<P>
  • 可选字段:
    • IsNil, NotNil

Edge 断言

  • HasEdge. 例如,对于一个 Pet 类型的 edge owner 来说 ,可以使用:

    1. client.Pet.
    2. Query().
    3. Where(pet.HasOwner()).
    4. All(ctx)
  • HasEdgeWith. 也可以将断言表示为集合的形式

    1. client.Pet.
    2. Query().
    3. Where(pet.HasOwnerWith(user.Name("a8m"))).
    4. All(ctx)

否定 (NOT)

  1. client.Pet.
  2. Query().
  3. Where(pet.Not(pet.NameHasPrefix("Ari"))).
  4. All(ctx)

析取 (OR)

  1. client.Pet.
  2. Query().
  3. Where(
  4. pet.Or(
  5. pet.HasOwner(),
  6. pet.Not(pet.HasFriends()),
  7. )
  8. ).
  9. All(ctx)

合取 (AND)

  1. client.Pet.
  2. Query().
  3. Where(
  4. pet.And(
  5. pet.HasOwner(),
  6. pet.Not(pet.HasFriends()),
  7. )
  8. ).
  9. All(ctx)

自定义断言

Custom predicates can be useful if you want to write your own dialect-specific logic or to control the executed queries.

Get all pets of users 1, 2 and 3

  1. pets := client.Pet.
  2. Query().
  3. Where(func(s *sql.Selector) {
  4. s.Where(sql.InInts(pet.FieldOwnerID, 1, 2, 3))
  5. }).
  6. AllX(ctx)

The above code will produce the following SQL query:

  1. SELECT DISTINCT `pets`.`id`, `pets`.`owner_id` FROM `pets` WHERE `owner_id` IN (1, 2, 3)

Count the number of users whose JSON field named URL contains the Scheme key

  1. count := client.User.
  2. Query().
  3. Where(func(s *sql.Selector) {
  4. s.Where(sqljson.HasKey(user.FieldURL, sqljson.Path("Scheme")))
  5. }).
  6. CountX(ctx)

The above code will produce the following SQL query:

  1. -- PostgreSQL
  2. SELECT COUNT(DISTINCT "users"."id") FROM "users" WHERE "url"->'Scheme' IS NOT NULL
  3. -- SQLite and MySQL
  4. SELECT COUNT(DISTINCT `users`.`id`) FROM `users` WHERE JSON_EXTRACT(`url`, "$.Scheme") IS NOT NULL

Get all users with a "Tesla" car

Consider an ent query such as:

  1. users := client.User.Query().
  2. Where(user.HasCarWith(car.Model("Tesla"))).
  3. AllX(ctx)

This query can be rephrased in 3 different forms: IN, EXISTS and JOIN.

  1. // `IN` version.
  2. users := client.User.Query().
  3. Where(func(s *sql.Selector) {
  4. t := sql.Table(car.Table)
  5. s.Where(
  6. sql.In(
  7. s.C(user.FieldID),
  8. sql.Select(t.C(user.FieldID)).From(t).Where(sql.EQ(t.C(car.FieldModel), "Tesla")),
  9. ),
  10. )
  11. }).
  12. AllX(ctx)
  13. // `JOIN` version.
  14. users := client.User.Query().
  15. Where(func(s *sql.Selector) {
  16. t := sql.Table(car.Table)
  17. s.Join(t).On(s.C(user.FieldID), t.C(car.FieldOwnerID))
  18. s.Where(sql.EQ(t.C(car.FieldModel), "Tesla"))
  19. }).
  20. AllX(ctx)
  21. // `EXISTS` version.
  22. users := client.User.Query().
  23. Where(func(s *sql.Selector) {
  24. t := sql.Table(car.Table)
  25. p := sql.And(
  26. sql.EQ(t.C(car.FieldModel), "Tesla"),
  27. sql.ColumnsEQ(s.C(user.FieldID), t.C(car.FieldOwnerID)),
  28. )
  29. s.Where(sql.Exists(sql.Select().From(t).Where(p)))
  30. }).
  31. AllX(ctx)

The above code will produce the following SQL query:

  1. -- `IN` version.
  2. SELECT DISTINCT `users`.`id`, `users`.`age`, `users`.`name` FROM `users` WHERE `users`.`id` IN (SELECT `cars`.`id` FROM `cars` WHERE `cars`.`model` = 'Tesla')
  3. -- `JOIN` version.
  4. SELECT DISTINCT `users`.`id`, `users`.`age`, `users`.`name` FROM `users` JOIN `cars` ON `users`.`id` = `cars`.`owner_id` WHERE `cars`.`model` = 'Tesla'
  5. -- `EXISTS` version.
  6. SELECT DISTINCT `users`.`id`, `users`.`age`, `users`.`name` FROM `users` WHERE EXISTS (SELECT * FROM `cars` WHERE `cars`.`model` = 'Tesla' AND `users`.`id` = `cars`.`owner_id`)

Get all pets where pet name contains a specific pattern

The generated code provides the HasPrefix, HasSuffix, Contains, and ContainsFold predicates for pattern matching. However, in order to use the LIKE operator with a custom pattern, use the following example.

  1. pets := client.Pet.Query().
  2. Where(func(s *sql.Selector){
  3. s.Where(sql.Like(pet.Name,"_B%"))
  4. }).
  5. AllX(ctx)

The above code will produce the following SQL query:

  1. SELECT DISTINCT `pets`.`id`, `pets`.`owner_id`, `pets`.`name`, `pets`.`age`, `pets`.`species` FROM `pets` WHERE `name` LIKE '_B%'