我正在使用以下go文件作为我的http API和mgo之间的层:
package store
import (
"reflect"
"strings"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
)
type Manager struct {
collection *mgo.Collection
}
type Model interface {
Id() bson.ObjectId
}
func (m *Manager) index(model Model) {
v := reflect.ValueOf(model).Elem()
var index, unique []string
for i := 0; i < v.NumField(); i++ {
t := v.Type().Field(i)
if s := t.Tag.Get("store"); len(s) != 0 {
if strings.Contains(s, "index") {
index = append(index, t.Name)
}
if strings.Contains(s, "unique") {
unique = append(unique, t.Name)
}
}
}
m.collection.EnsureIndex(mgo.Index{Key: index})
m.collection.EnsureIndex(mgo.Index{Key: unique, Unique: true})
}
func (m *Manager) Create(model Model) error {
m.index(model)
return m.collection.Insert(model)
}
func (m *Manager) Update(model Model) error {
m.index(model)
return m.collection.UpdateId(model.Id(), model)
}
func (m *Manager) Destroy(model Model) error {
m.index(model)
return m.collection.RemoveId(model.Id())
}
func (m *Manager) Find(query Query, models interface{}) error {
return m.collection.Find(query).All(models)
}
func (m *Manager) FindOne(query Query, model Model) error {
m.index(model)
return m.collection.Find(query).One(model)
}
如您所见,我通过调用m.index(model)
确保每项操作的索引。模型类型包含store:"index"
或store:"unique"
形式的标记。
由于设置常规索引与设置唯一索引不同,我会单独收集它们,然后在已解析的密钥上调用m.collection.EnsureIndex
。
但是,对m.collection.EnsureIndex
的第二次调用永远不会到达服务器,只会发送正常索引。
查看godocs节目,确保索引缓存其调用,因此我认为我应该在一次调用中将它们合并。
那么如何在一次调用中将不同的索引设置合并到EnsureIndex?
解决方案: 您需要从反射中小写字段名称以使用它们与mgo ...
答案 0 :(得分:2)
问题描述似乎暗示您在同一组字段上具有唯一且非唯一的索引。这是一个额外的不必要的开销..在这些情况下只需创建一个唯一索引。