mongo golang driver remove all array items without condition

huangapple go评论119阅读模式
英文:

mongo golang driver remove all array items without condition

问题

我需要在MongoDB中删除并获取数组的所有元素。我找到了$pull$pullAll,但它们需要查询条件,如何在没有条件的情况下删除所有元素?

代码不起作用,使用$pull后元素仍然存在:

  1. var UserId = 123
  2. type Event struct {
  3. UserId uint64 `gorm:"uniqueIndex"`
  4. Array [][]byte
  5. }
  6. func main() {
  7. var DB_NAME = "test"
  8. var ctx = context.Background()
  9. client, _ := mongo.Connect(
  10. ctx, options.Client().ApplyURI("mongodb://localhost"))
  11. col := client.Database("test").Collection(`Test`)
  12. { // pull items
  13. r := col.FindOneAndUpdate(ctx, bson.M{
  14. `UserId`: UserId,
  15. }, bson.M{
  16. `$pull`: bson.M{
  17. `Array`: nil,
  18. },
  19. }, options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.Before))
  20. if r.Err() != nil {
  21. panic(r.Err())
  22. }
  23. }
  24. }

编辑

我发现$set: bson.M{"Array": [][]byte{}}可以完成任务,$pull能够做到这一点吗?哪个性能更好?

英文:

I need to remove and get all elements of an array in mongodb. I found $pull and $pullAll but they require query condition, how to remove all elements without condition?

The code not work, elements still exist after the $pull:

  1. var UserId = 123
  2. type Event struct {
  3. UserId uint64 `gorm:"uniqueIndex"`
  4. Array [][]byte
  5. }
  6. func main() {
  7. var DB_NAME = "test"
  8. var ctx = context.Background()
  9. client, _ := mongo.Connect(
  10. ctx, options.Client().ApplyURI("mongodb://localhost"))
  11. col := client.Database("test").Collection(`Test`)
  12. { // pull items
  13. r := col.FindOneAndUpdate(ctx, bson.M{
  14. `UserId`: UserId,
  15. }, bson.M{
  16. `$pull`: bson.M{
  17. `Array`: nil,
  18. },
  19. }, options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.Before))
  20. if r.Err() != nil {
  21. panic(r.Err())
  22. }
  23. }
  24. }

Edit:

I found $set': bson.M{"Array": [][]byte{}} does the job, is $pull capable of doing this? Which performance is better?

答案1

得分: 1

$pull 操作符是更新语句中的“顶级”操作符,所以你的顺序是错误的:

  1. r := col.FindOneAndUpdate(ctx, bson.M{bson.M{"$pull": bson.M{"UserId": bson.ObjectIdHex(UserId)}}})

更新操作符的顺序总是先操作符,再是动作。

如果在“顶级”键中没有操作符,MongoDB 将其解释为要更新和替换匹配的文档的“普通对象”。因此会出现关于键名中 $ 的错误。

英文:

The $pull operator is a "top level" operator in update statements, so you simply have this the wrong way around:

  1. r := col.FindOneAndUpdate(ctx, bson.M{bson.M{"$pull": bson.M{"UserId": bson.ObjectIdHex(UserId)}}

The order of update operators is always operator first, action second.

If there is no operator at the "top-level" keys, MongoDB interprets this as just a "plain object" to update and "replace" the matched document. Hence the error about the $ in the key name.

huangapple
  • 本文由 发表于 2021年10月17日 20:21:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/69604292.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定