File: schema-indexes.md

package info (click to toggle)
golang-github-facebook-ent 0.5.4-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 14,284 kB
  • sloc: javascript: 349; makefile: 8
file content (155 lines) | stat: -rwxr-xr-x 2,998 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
---
id: schema-indexes
title: Indexes
---

## Multiple Fields

Indexes can be configured on one or more fields in order to improve 
speed of data retrieval, or defining uniqueness.

```go
package schema

import (
	"github.com/facebook/ent"
	"github.com/facebook/ent/schema/index"
)

// User holds the schema definition for the User entity.
type User struct {
	ent.Schema
}

func (User) Indexes() []ent.Index {
	return []ent.Index{
        // non-unique index.
        index.Fields("field1", "field2"),
        // unique index.
        index.Fields("first_name", "last_name").
            Unique(),
	}
}
```

Note that for setting a single field as unique, use the `Unique`
method on the field builder as follows:

```go
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("phone").
			Unique(),
	}
}
```

## Index On Edges

Indexes can be configured on composition of fields and edges. The main use-case
is setting uniqueness on fields under a specific relation. Let's take an example:

![er-city-streets](https://entgo.io/assets/er_city_streets.png)

In the example above, we have a `City` with many `Street`s, and we want to set the
street name to be unique under each city.

`ent/schema/city.go`
```go
// City holds the schema definition for the City entity.
type City struct {
	ent.Schema
}

// Fields of the City.
func (City) Fields() []ent.Field {
	return []ent.Field{
		field.String("name"),
	}
}

// Edges of the City.
func (City) Edges() []ent.Edge {
	return []ent.Edge{
		edge.To("streets", Street.Type),
	}
}
```

`ent/schema/street.go`
```go
// Street holds the schema definition for the Street entity.
type Street struct {
	ent.Schema
}

// Fields of the Street.
func (Street) Fields() []ent.Field {
	return []ent.Field{
		field.String("name"),
	}
}

// Edges of the Street.
func (Street) Edges() []ent.Edge {
	return []ent.Edge{
		edge.From("city", City.Type).
			Ref("streets").
			Unique(),
	}
}

// Indexes of the Street.
func (Street) Indexes() []ent.Index {
	return []ent.Index{
		index.Fields("name").
			Edges("city").
			Unique(),
	}
}
```

`example.go`
```go
func Do(ctx context.Context, client *ent.Client) error {
	// Unlike `Save`, `SaveX` panics if an error occurs.
	tlv := client.City.
		Create().
		SetName("TLV").
		SaveX(ctx)
	nyc := client.City.
		Create().
		SetName("NYC").
		SaveX(ctx)
	// Add a street "ST" to "TLV".
	client.Street.
		Create().
		SetName("ST").
		SetCity(tlv).
		SaveX(ctx)
	// This operation will fail because "ST"
	// is already created under "TLV".
	_, err := client.Street.
		Create().
		SetName("ST").
		SetCity(tlv).
		Save(ctx)
	if err == nil {
		return fmt.Errorf("expecting creation to fail")
	}
	// Add a street "ST" to "NYC".
	client.Street.
		Create().
		SetName("ST").
		SetCity(nyc).
		SaveX(ctx)
	return nil
}
```

The full example exists in [GitHub](https://github.com/facebook/ent/tree/master/examples/edgeindex).

## Dialect Support

Indexes currently support only SQL dialects, and do not support Gremlin.