109 lines
2.4 KiB
Go
109 lines
2.4 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 {
|
||
|
col := db.C(GetCollectionName(m))
|
||
|
|
||
|
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 for field %s in model %+v", bsonField, t)
|
||
|
}
|
||
|
|
||
|
}
|
||
|
if len(index.Key) > 0 {
|
||
|
// fmt.Println(bsonField, index)
|
||
|
fmt.Printf("ensure index on collection %s for field %s\n", GetCollectionName(m), 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 for fields %v\n", GetCollectionName(m), textFields)
|
||
|
err := col.EnsureIndex(mgo.Index{
|
||
|
Name: "textindex",
|
||
|
Key: textFields,
|
||
|
DefaultLanguage: "german",
|
||
|
Background: false,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|