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 }