2018-03-20 14:16:01 +01:00
|
|
|
package mgocrud
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
mgo "gopkg.in/mgo.v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
// EnsureIndex ensured mongodb index reflecting model struct index tag
|
2022-02-09 21:57:31 +01:00
|
|
|
func (db *MgoDatabase) EnsureIndex(m ModelInterface) error {
|
2019-11-28 11:28:26 +01:00
|
|
|
colName := GetCollectionName(m)
|
|
|
|
col := db.C(colName)
|
2018-03-20 14:16:01 +01:00
|
|
|
|
|
|
|
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:
|
2022-02-09 15:11:15 +01:00
|
|
|
return fmt.Errorf("invalid index tag on collection %s.%s for field %s%s in model %+v", db.Name(), colName, fieldbase, bsonField, t)
|
2018-03-20 14:16:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if len(index.Key) > 0 {
|
|
|
|
// fmt.Println(bsonField, index)
|
2022-02-09 15:11:15 +01:00
|
|
|
fmt.Printf("ensure index on collection %s.%s for field %s%s\n", db.Name(), colName, fieldbase, bsonField)
|
|
|
|
err := col.EnsureIndex(NewMgoIndex(index))
|
2018-03-20 14:16:01 +01:00
|
|
|
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)
|
2022-02-09 15:11:15 +01:00
|
|
|
fmt.Printf("ensure text index on collection %s.%s for fields %v\n", db.Name(), GetCollectionName(m), textFields)
|
|
|
|
err := col.EnsureIndex(NewMgoIndex(mgo.Index{
|
2018-03-20 14:16:01 +01:00
|
|
|
Name: "textindex",
|
|
|
|
Key: textFields,
|
|
|
|
DefaultLanguage: "german",
|
|
|
|
Background: false,
|
2022-02-09 15:11:15 +01:00
|
|
|
}))
|
2018-03-20 14:16:01 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|