mongo golang driver remove all array items without condition

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

mongo golang driver remove all array items without condition

问题

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

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

var UserId = 123

type Event struct {
	UserId uint64 `gorm:"uniqueIndex"`
	Array  [][]byte
}

func main() {
	var DB_NAME = "test"
	var ctx = context.Background()
	client, _ := mongo.Connect(
		ctx, options.Client().ApplyURI("mongodb://localhost"))

	col := client.Database("test").Collection(`Test`)

	{ // pull items

		r := col.FindOneAndUpdate(ctx, bson.M{
			`UserId`: UserId,
		}, bson.M{
			`$pull`: bson.M{
				`Array`: nil,
			},
		}, options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.Before))

		if r.Err() != nil {
			panic(r.Err())
		}
	}
}

编辑

我发现$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:

var UserId = 123

type Event struct {
	UserId uint64 `gorm:"uniqueIndex"`
	Array  [][]byte
}

func main() {
	var DB_NAME = "test"
	var ctx = context.Background()
	client, _ := mongo.Connect(
		ctx, options.Client().ApplyURI("mongodb://localhost"))

	col := client.Database("test").Collection(`Test`)

	{ // pull items

		r := col.FindOneAndUpdate(ctx, bson.M{
			`UserId`: UserId,
		}, bson.M{
			`$pull`: bson.M{
				`Array`: nil,
			},
		}, options.FindOneAndUpdate().SetUpsert(true).SetReturnDocument(options.Before))

		if r.Err() != nil {
			panic(r.Err())
		}
	}
}


Edit:

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

答案1

得分: 1

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

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:

 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:

确定