Skip to content

Commit 44d60f4

Browse files
authored
Merge pull request #92 from jiangz222/daily
new indexes operation
2 parents 7ff5154 + fee98dc commit 44d60f4

File tree

5 files changed

+129
-63
lines changed

5 files changed

+129
-63
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ var userInfo = UserInfo{
9696
Create index
9797

9898
```go
99-
cli.EnsureIndexes(ctx, []string{}, []string{"age", "name,weight"})
99+
cli.CreateOneIndex(context.Background(), options.IndexModel{Key: []string{"name"}, Unique: true})
100+
cli.CreateIndexes(context.Background(), []options.IndexModel{{Key: []string{"id2", "id3"}}})
100101
```
101102

102103
- Insert a document

README_ZH.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ var userInfo = UserInfo{
9292
创建索引
9393

9494
```go
95-
cli.EnsureIndexes(ctx, []string{}, []string{"age", "name,weight"})
95+
cli.CreateOneIndex(context.Background(), options.IndexModel{Key: []string{"name"}, Unique: true})
96+
cli.CreateIndexes(context.Background(), []options.IndexModel{{Key: []string{"id2", "id3"}}})
9697
```
9798

9899
- 插入一个文档

collection.go

Lines changed: 61 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@ package qmgo
33
import (
44
"context"
55
"fmt"
6-
"reflect"
7-
"strings"
8-
96
"github.com/qiniu/qmgo/field"
107
"github.com/qiniu/qmgo/hook"
118
opts "github.com/qiniu/qmgo/options"
129
"go.mongodb.org/mongo-driver/bson"
1310
"go.mongodb.org/mongo-driver/mongo"
1411
"go.mongodb.org/mongo-driver/mongo/options"
1512
"go.mongodb.org/mongo-driver/x/bsonx"
13+
"reflect"
14+
"strings"
1615
)
1716

1817
// Collection is a handle to a MongoDB collection
@@ -294,77 +293,104 @@ func (c *Collection) Aggregate(ctx context.Context, pipeline interface{}) Aggreg
294293
// Example:indexes = []string{"idx1", "-idx2", "idx3,idx4"}
295294
// Three indexes will be created, index idx1 with ascending order, index idx2 with descending order, idex3 and idex4 are Compound ascending sort index
296295
// Reference: https://docs.mongodb.com/manual/reference/command/createIndexes/
297-
func (c *Collection) ensureIndex(ctx context.Context, indexes []string, isUnique bool) {
296+
func (c *Collection) ensureIndex(ctx context.Context, indexes []opts.IndexModel) error {
298297
var indexModels []mongo.IndexModel
299298

300299
// 组建[]mongo.IndexModel
301300
for _, idx := range indexes {
302301
var model mongo.IndexModel
303302
var keysDoc bsonx.Doc
304303

305-
colIndexArr := strings.Split(idx, ",")
306-
for _, field := range colIndexArr {
304+
for _, field := range idx.Key {
307305
key, n := SplitSortField(field)
308306

309307
keysDoc = keysDoc.Append(key, bsonx.Int32(n))
310308
}
311-
309+
iOptions := options.Index().SetUnique(idx.Unique).SetBackground(idx.Background).SetSparse(idx.Sparse)
310+
if idx.ExpireAfterSeconds != nil {
311+
iOptions.SetExpireAfterSeconds(*idx.ExpireAfterSeconds)
312+
}
312313
model = mongo.IndexModel{
313314
Keys: keysDoc,
314-
Options: options.Index().SetUnique(isUnique),
315+
Options: iOptions,
315316
}
316317

317318
indexModels = append(indexModels, model)
318319
}
319320

320321
if len(indexModels) == 0 {
321-
return
322+
return nil
322323
}
323324

324-
var err error
325-
var res []string
326-
res, err = c.collection.Indexes().CreateMany(ctx, indexModels)
327-
325+
res, err := c.collection.Indexes().CreateMany(ctx, indexModels)
328326
if err != nil || len(res) == 0 {
329-
s := fmt.Sprint("<MongoDB.C>: ", c.collection.Name(), " Index: ", indexes, " error: ", err, "res: ", res)
330-
panic(s)
327+
fmt.Println("<MongoDB.C>: ", c.collection.Name(), " Index: ", indexes, " error: ", err, "res: ", res)
328+
return err
331329
}
332-
return
330+
return nil
333331
}
334332

333+
// EnsureIndexes Deprecated
334+
// Recommend to use CreateIndexes / CreateOneIndex for more function)
335335
// EnsureIndexes creates unique and non-unique indexes in collection
336-
func (c *Collection) EnsureIndexes(ctx context.Context, uniques []string, indexes []string) {
337-
// 创建唯一索引
338-
if len(uniques) != 0 {
339-
c.ensureIndex(ctx, uniques, true)
336+
// the combination of indexes is different from CreateIndexes:
337+
// if uniques/indexes is []string{"name"}, means create index "name"
338+
// if uniques/indexes is []string{"name,-age","uid"} means create Compound indexes: name and -age, then create one index: uid
339+
func (c *Collection) EnsureIndexes(ctx context.Context, uniques []string, indexes []string) (err error) {
340+
uniqueModel, indexesModel := []opts.IndexModel{}, []opts.IndexModel{}
341+
for _, v := range uniques {
342+
vv := strings.Split(v, ",")
343+
model := opts.IndexModel{Key: vv, Unique: true}
344+
uniqueModel = append(uniqueModel, model)
345+
}
346+
if err = c.CreateIndexes(ctx, uniqueModel); err != nil {
347+
return
340348
}
341349

342-
// 创建普通索引
343-
if len(indexes) != 0 {
344-
c.ensureIndex(ctx, indexes, false)
350+
for _, v := range indexes {
351+
vv := strings.Split(v, ",")
352+
model := opts.IndexModel{Key: vv}
353+
indexesModel = append(uniqueModel, model)
354+
}
355+
if err = c.CreateIndexes(ctx, indexesModel); err != nil {
356+
return
345357
}
358+
return
359+
}
346360

361+
// CreateIndexes creates multiple indexes in collection
362+
// If the Key in opts.IndexModel is []string{"name"}, means create index: name
363+
// If the Key in opts.IndexModel is []string{"name","-age"} means create Compound indexes: name and -age
364+
func (c *Collection) CreateIndexes(ctx context.Context, indexes []opts.IndexModel) (err error) {
365+
// 创建普通索引
366+
err = c.ensureIndex(ctx, indexes)
347367
return
348368
}
349369

350-
// DropIndexes drop indexes in collection, indexes that be dropped should be in line with inputting indexes
351-
func (c *Collection) DropIndexes(ctx context.Context, indexes []string) error {
370+
// CreateIndex creates one index
371+
// If the Key in opts.IndexModel is []string{"name"}, means create index name
372+
// If the Key in opts.IndexModel is []string{"name","-age"} means drop Compound indexes: name and -age
373+
func (c *Collection) CreateOneIndex(ctx context.Context, indexes opts.IndexModel) error {
374+
// 创建普通索引
375+
return c.ensureIndex(ctx, []opts.IndexModel{indexes})
352376

353-
var err error
354-
for _, index := range indexes {
355-
_, err = c.collection.Indexes().DropOne(ctx, generateDroppedIndex(index))
356-
if err != nil {
357-
return err
358-
}
377+
}
378+
379+
// DropIndex drop indexes in collection, indexes that be dropped should be in line with inputting indexes
380+
// The indexes is []string{"name"} means drop index: name
381+
// The indexes is []string{"name","-age"} means drop Compound indexes: name and -age
382+
func (c *Collection) DropIndex(ctx context.Context, indexes []string) error {
383+
_, err := c.collection.Indexes().DropOne(ctx, generateDroppedIndex(indexes))
384+
if err != nil {
385+
return err
359386
}
360387
return err
361388
}
362389

363-
// generate indexes that store in mongo which may consist more than one index(like "index1,index2" is stored as "index1_1_index2_1")
364-
func generateDroppedIndex(index string) string {
390+
// generate indexes that store in mongo which may consist more than one index(like []string{"index1","index2"} is stored as "index1_1_index2_1")
391+
func generateDroppedIndex(index []string) string {
365392
var res string
366-
s := strings.Split(index, ",")
367-
for _, e := range s {
393+
for _, e := range index {
368394
key, sort := SplitSortField(e)
369395
n := key + "_" + fmt.Sprint(sort)
370396
if len(res) == 0 {

collection_test.go

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ package qmgo
22

33
import (
44
"context"
5+
"github.com/qiniu/qmgo/options"
6+
"testing"
7+
58
"github.com/qiniu/qmgo/operator"
69
"github.com/stretchr/testify/require"
710
"go.mongodb.org/mongo-driver/bson"
811
"go.mongodb.org/mongo-driver/bson/primitive"
9-
"testing"
1012
)
1113

1214
func TestCollection_EnsureIndex(t *testing.T) {
@@ -15,13 +17,13 @@ func TestCollection_EnsureIndex(t *testing.T) {
1517
defer cli.Close(context.Background())
1618
defer cli.DropCollection(context.Background())
1719

18-
cli.ensureIndex(context.Background(), nil, false)
19-
cli.ensureIndex(context.Background(), []string{"id1"}, true)
20-
cli.ensureIndex(context.Background(), []string{"id2,id3"}, false)
21-
cli.ensureIndex(context.Background(), []string{"id4,-id5"}, false)
20+
cli.ensureIndex(context.Background(), nil)
21+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"id1"}, Unique: true}})
22+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"id2", "id3"}}})
23+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"id4", "-id5"}}})
2224

23-
// same index,panic
24-
ast.Panics(func() { cli.ensureIndex(context.Background(), []string{"id1"}, false) })
25+
// same index,error
26+
ast.Error(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"id1"}}}))
2527

2628
// check if unique indexs is working
2729
var err error
@@ -47,8 +49,35 @@ func TestCollection_EnsureIndexes(t *testing.T) {
4749
common := []string{"id2,id3", "id4,-id5"}
4850
cli.EnsureIndexes(context.Background(), unique, common)
4951

50-
// same index,panic
51-
ast.Panics(func() { cli.EnsureIndexes(context.Background(), nil, unique) })
52+
// same index,error
53+
ast.Error(cli.EnsureIndexes(context.Background(), nil, unique))
54+
55+
// check if unique indexs is working
56+
var err error
57+
doc := bson.M{
58+
"id1": 1,
59+
}
60+
61+
_, err = cli.InsertOne(context.Background(), doc)
62+
ast.NoError(err)
63+
_, err = cli.InsertOne(context.Background(), doc)
64+
ast.Equal(true, IsDup(err))
65+
}
66+
67+
func TestCollection_CreateIndexes(t *testing.T) {
68+
ast := require.New(t)
69+
cli := initClient("test")
70+
defer cli.Close(context.Background())
71+
defer cli.DropCollection(context.Background())
72+
73+
var expireS int32 = 100
74+
unique := []string{"id1"}
75+
ast.NoError(cli.CreateOneIndex(context.Background(), options.IndexModel{Key: unique, Unique: true, ExpireAfterSeconds: &expireS}))
76+
77+
ast.NoError(cli.CreateIndexes(context.Background(), []options.IndexModel{{Key: []string{"id2", "id3"}},
78+
{Key: []string{"id4", "-id5"}}}))
79+
// same index,error
80+
ast.Error(cli.CreateOneIndex(context.Background(), options.IndexModel{Key: unique}))
5281

5382
// check if unique indexs is working
5483
var err error
@@ -68,36 +97,36 @@ func TestCollection_DropIndex(t *testing.T) {
6897
cli := initClient("test")
6998
defer cli.DropCollection(context.Background())
7099

71-
cli.ensureIndex(context.Background(), []string{"index1"}, true)
100+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index1"}, Unique: true}})
72101

73-
// same index,panic
74-
ast.Panics(func() { cli.ensureIndex(context.Background(), []string{"index1"}, false) })
102+
// same index,error
103+
ast.Error(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index1"}}}))
75104

76-
err := cli.DropIndexes(context.Background(), []string{"index1"})
105+
err := cli.DropIndex(context.Background(), []string{"index1"})
77106
ast.NoError(err)
78-
ast.NotPanics(func() { cli.ensureIndex(context.Background(), []string{"index1"}, false) })
107+
ast.NoError(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index1"}}}))
79108

80-
cli.ensureIndex(context.Background(), []string{"-index1"}, true)
81-
// same index,panic
82-
ast.Panics(func() { cli.ensureIndex(context.Background(), []string{"-index1"}, false) })
109+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"-index1"}, Unique: true}})
110+
// same index,error
111+
ast.Error(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"-index1"}}}))
83112

84-
err = cli.DropIndexes(context.Background(), []string{"-index1"})
113+
err = cli.DropIndex(context.Background(), []string{"-index1"})
85114
ast.NoError(err)
86-
ast.NotPanics(func() { cli.ensureIndex(context.Background(), []string{"-index1"}, false) })
115+
ast.NoError(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"-index1"}}}))
87116

88-
err = cli.DropIndexes(context.Background(), []string{""})
117+
err = cli.DropIndex(context.Background(), []string{""})
89118
ast.Error(err)
90119

91-
err = cli.DropIndexes(context.Background(), []string{"index2"})
120+
err = cli.DropIndex(context.Background(), []string{"index2"})
92121
ast.Error(err)
93122

94-
cli.ensureIndex(context.Background(), []string{"index2,-index1"}, true)
95-
ast.Panics(func() { cli.ensureIndex(context.Background(), []string{"index2,-index1"}, false) })
96-
err = cli.DropIndexes(context.Background(), []string{"index2,-index1"})
123+
cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index2", "-index1"}, Unique: true}})
124+
ast.Error(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index2", "-index1"}}}))
125+
err = cli.DropIndex(context.Background(), []string{"index2", "-index1"})
97126
ast.NoError(err)
98-
ast.NotPanics(func() { cli.ensureIndex(context.Background(), []string{"index2,-index1"}, false) })
127+
ast.NoError(cli.ensureIndex(context.Background(), []options.IndexModel{{Key: []string{"index2", "-index1"}}}))
99128

100-
err = cli.DropIndexes(context.Background(), []string{"-"})
129+
err = cli.DropIndex(context.Background(), []string{"-"})
101130
ast.Error(err)
102131
}
103132

options/index_options.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package options
2+
3+
type IndexModel struct {
4+
Key []string // Index key fields; prefix name with dash (-) for descending order
5+
Unique bool // Prevent two documents from having the same index key
6+
Background bool // Build index in background and return immediately
7+
Sparse bool // Only index documents containing the Key fields
8+
ExpireAfterSeconds *int32 // Periodically delete docs with indexed time.Time older than that.
9+
}

0 commit comments

Comments
 (0)