英文:
mgo: how to update a specific array in a document
问题
我在数据库中有这个文档:
[
{
"_id": "53dc97bf91f1f933e15d6fb1",
"attributes": {
"chilled": false,
"flammable": false,
"food": false,
"fragile": false,
"frozen": false,
"hot": false,
"outsized": false
},
"createdAt": "02/08/14 09:48:16",
"customer": "53d68bc091f1f933e15d6f90",
"location": [
{
"count": 0,
"warehouse": "53db430c91f1f933e15d6fa6"
},
{
"count": 34,
"warehouse": "53db430c91g1f933e45d6fa4"
}
],
"name": "test",
"type": "stored",
"updatedAt": ""
}
]
如果我知道仓库的ID,我该如何更新location数组?
这是我现在的代码:
coll := p.GetDb().C("product")
changes := bson.M {
"location": bson.M {
"$elemMatch": bson.M {
"warehouse": bson.ObjectIdHex(warehouseId),
},
},
"$set": bson.M {
"location.$.count": 4,
},
}
err := coll.UpdateId(bson.ObjectIdHex(productId), changes)
if err != nil {
http.Error(res, err.Error(), 500)
return
}
但是出现了这个错误:
在“location.$elemMatch”中,以美元符号($)为前缀的字段“$elemMatch”对于存储无效。
英文:
I have this document inside my database:
[
{
"_id": "53dc97bf91f1f933e15d6fb1",
"attributes": {
"chilled": false,
"flammable": false,
"food": false,
"fragile": false,
"frozen": false,
"hot": false,
"outsized": false
},
"createdAt": "02/08/14 09:48:16",
"customer": "53d68bc091f1f933e15d6f90",
"location": [
{
"count": 0,
"warehouse": "53db430c91f1f933e15d6fa6"
},
{
"count": 34,
"warehouse": "53db430c91g1f933e45d6fa4"
},
],
"name": "test",
"type": "stored",
"updatedAt": ""
}
]
How can i update the location array if i know the warehouse Id?
This is what i have now
coll := p.GetDb().C("product")
changes := bson.M {
"location": bson.M {
"$elemMatch": bson.M {
"warehouse": bson.ObjectIdHex(warehouseId),
},
},
"$set": bson.M {
"location.$.count": 4,
},
}
err := coll.UpdateId(bson.ObjectIdHex(productId), changes)
if err != nil {
http.Error(res, err.Error(), 500)
return
}
But get this error:
> The dollar ($) prefixed field '$elemMatch' in 'location.$elemMatch' is not valid for storage.
答案1
得分: 12
你把顺序写错了。在你的语句中,匹配仓库 "id" 值的部分应该放在 "query" 部分,而不是 "update" 部分。因此,你不需要使用 UpdateId
,而是使用 Update
,因为它允许更广泛的查询选择:
query := bson.M{
"_id": bson.ObjectIdHex(productId),
"location.warehouse": bson.ObjectIdHex(warehouseId)
}
update := bson.M{
"$set": bson.M{
"location.$.count": 4
}
}
err := coll.Update(query, update)
另外,请注意,在这里使用 "点表示法" 是可以的,因为你对数组元素的选择器只是一个单一的字段。只有当数组中有多个字段需要进行匹配时,才需要使用 $elemMatch
。
英文:
You wrote this the wrong way around. The match on the warehouse "id" value belongs in the "query" portion of your statement and not in the "update" section. As such, you don't want the UpdateId
variant, but the Update
as it allows a wider query selection:
query := bson.M{
"_id": bson.ObjectIdHex(productId),
"location.warehouse": bson.ObjectIdHex(warehouseId)
}
update := bson.M{
"$set": bson.M{
"location.$.count": 4
}
}
err := coll.Update(query,update)
Also note that the the "dot notation" form is fine here as your selector for the array element is just a singular field. You typically only need $elemMatch
when there is more that one field in the array to establish the match.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论