使用用于 MongoDB的Labix mgo API,我正在尝试对分片集合执行增量操作。我可以使用通常的 mgo.Change 结构在未分片的集合上执行此操作,但是当我尝试在分片集合上执行此操作时,出现错误:full shard key must be in update object for collection: db_name.collection_name
适用于未分片集合的原始代码如下所示:
change := mgo.Change{
ReturnNew: true,
Upsert: true,
Update: bson.M{
"$setOnInsert": bson.M{
"ci": r.Ci,
"dt": r.Dt,
"zi": r.Zi,
},
"$inc": &data,
},
}
_, err := collection.Upsert(bson.M{"_id": id, "ci": r.Ci, "dt": r.Dt, "zi": r.Zi}, change); if err != nil {
log.Println("FAILURE", err)
}
但是,当我切换到分片集合时,在键上分片时{ci: 1, dt: 1, zi: 1}出现上述错误。
在尝试调试时,我试图弄清楚 mgo 幕后发生了什么,并尝试直接插入 mongo 终端。
db.collection.update({ "_id" : "98364_2013-12-11", "ci" : "16326", "dt" : "2013-12-11", "zi" : "98364"}, {$setOnInsert: { "ci" : "16326", "dt" : "2013-12-11", "zi" : "98364"} , $inc: {test :1}}, { upsert: true });
然而,这给我带来了一个单独的错误:Can't modify shard key's value. field: ci: "16326" collection: db.collection这是我认为一旦我弄清楚我的初始错误就必须弄清楚的事情,但对我来说似乎很奇怪它用 $setOnInsert 命令抛出这个错误,因为它不应该修改值,只需在初始插入时设置它。当我删除命令的 $setOnInsert 部分时,所有错误都会消失,但我需要一种方法来确保这些值得到设置,因为它们在我编写的查询中很重要以取回数据。
回到我的主要问题:我确实发现当我在与MongoDB终端交互时重新排列更新和upsert文档的顺序时,我得到了我在通过mgo时得到的错误,所以我试图非常严格地控制通过切换到 bson.D 在 mgo.Change 结构中传递的文档顺序:
相关分类