110 lines
2.5 KiB
Go
110 lines
2.5 KiB
Go
package mgocrud
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
mgo "gopkg.in/mgo.v2"
|
|
)
|
|
|
|
// EnsureIndex ensured mongodb index reflecting model struct index tag
|
|
func EnsureIndex(db *mgo.Database, m ModelInterface) error {
|
|
colName := GetCollectionName(m)
|
|
col := db.C(colName)
|
|
|
|
mType := reflect.TypeOf(m)
|
|
|
|
textFields := []string{}
|
|
|
|
var _indexWalk func(t reflect.Type, fieldbase string) error
|
|
_indexWalk = func(t reflect.Type, fieldbase string) error {
|
|
|
|
for i := 0; i < 2; i++ {
|
|
if t.Kind() == reflect.Ptr || t.Kind() == reflect.Slice {
|
|
t = t.Elem()
|
|
}
|
|
}
|
|
|
|
if t.Kind() == reflect.Struct {
|
|
|
|
for i := 0; i < t.NumField(); i++ {
|
|
field := t.Field(i)
|
|
indexTag := field.Tag.Get("index")
|
|
|
|
bsonField := strings.Split(field.Tag.Get("bson"), ",")[0]
|
|
if bsonField == "" {
|
|
bsonField = strings.ToLower(field.Name)
|
|
}
|
|
|
|
if bsonField != "-" {
|
|
if indexTag != "" {
|
|
index := mgo.Index{
|
|
Background: false,
|
|
Sparse: false,
|
|
Unique: false,
|
|
}
|
|
for _, indexEl := range strings.Split(indexTag, ",") {
|
|
switch {
|
|
case indexEl == "single":
|
|
index.Key = []string{fieldbase + bsonField}
|
|
case indexEl == "unique":
|
|
index.Unique = true
|
|
case indexEl == "sparse":
|
|
index.Sparse = true
|
|
case indexEl == "background":
|
|
index.Background = true
|
|
case indexEl == "text":
|
|
textFields = append(textFields, "$text:"+fieldbase+bsonField)
|
|
default:
|
|
return fmt.Errorf("invalid index tag on collection %s.%s for field %s%s in model %+v", db.Name, colName, fieldbase, bsonField, t)
|
|
}
|
|
|
|
}
|
|
if len(index.Key) > 0 {
|
|
// fmt.Println(bsonField, index)
|
|
fmt.Printf("ensure index on collection %s.%s for field %s%s\n", db.Name, colName, fieldbase, bsonField)
|
|
err := col.EnsureIndex(index)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
fBase := bsonField + "."
|
|
if field.Anonymous {
|
|
fBase = ""
|
|
}
|
|
err := _indexWalk(field.Type, fBase)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
err := _indexWalk(mType, "")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(textFields) > 0 {
|
|
// fmt.Println("$text", textFields)
|
|
fmt.Printf("ensure text index on collection %s.%s for fields %v\n", db.Name, GetCollectionName(m), textFields)
|
|
err := col.EnsureIndex(mgo.Index{
|
|
Name: "textindex",
|
|
Key: textFields,
|
|
DefaultLanguage: "german",
|
|
Background: false,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|