如何使用Golang删除MongoDB数组字段中指定下标位置的元素
Go语言操作MongoDB删除数组指定下标元素的实现方案
以下实现基于官方MongoDB Go驱动 go.mongodb.org/mongo-driver/mongo。
场景1:删除expenses数组第一个元素(下标0)
直接使用$pop操作符即可实现,性能最优,仅需一次请求,完全匹配你期望的expenses[0].Delete()效果:
import ( "context" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) func DeleteFirstExpense(client *mongo.Client) error { // 构造查询条件,匹配指定_id的文档 objID, err := primitive.ObjectIDFromHex("12") if err != nil { return err } filter := bson.M{"_id": objID} // $pop传-1表示删除数组第一个元素 update := bson.M{ "$pop": bson.M{"expenses": -1}, } // 执行更新 collection := client.Database("你的库名").Collection("你的集合名") _, err = collection.UpdateOne(context.TODO(), filter, update) return err }
$pop操作符取值为1时可直接删除数组末尾元素,适合删除最后一个元素的场景。
场景2:删除expenses数组第二个元素(下标1)或任意指定下标元素
方案A(兼容所有MongoDB版本):分两步操作
先将目标下标元素置为null,再移除数组中所有null元素:
import ( "context" "fmt" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/mongo" ) func DeleteExpenseByIndex(client *mongo.Client, targetIndex int) error { objID, err := primitive.ObjectIDFromHex("12") if err != nil { return err } filter := bson.M{"_id": objID} collection := client.Database("你的库名").Collection("你的集合名") // 第一步:将目标下标元素置为null unsetUpdate := bson.M{ "$unset": bson.M{fmt.Sprintf("expenses.%d", targetIndex): ""}, } _, err = collection.UpdateOne(context.TODO(), filter, unsetUpdate) if err != nil { return err } // 第二步:移除数组中所有null值 pullUpdate := bson.M{ "$pull": bson.M{"expenses": nil}, } _, err = collection.UpdateOne(context.TODO(), filter, pullUpdate) return err }
方案B(MongoDB 4.2+支持):聚合管道单次操作
使用$concatArrays和$slice拼接删除目标下标后的前后两段数组,仅需一次请求:
func DeleteExpenseByIndexV42(client *mongo.Client, targetIndex int) error { objID, err := primitive.ObjectIDFromHex("12") if err != nil { return err } filter := bson.M{"_id": objID} update := bson.A{ bson.M{ "$set": bson.M{ "expenses": bson.M{ "$concatArrays": []interface{}{ // 取目标下标之前的元素 bson.M{"$slice": []interface{}{"$expenses", targetIndex}}, // 取目标下标之后的元素 bson.M{"$slice": []interface{}{"$expenses", targetIndex + 1, bson.M{"$size": "$expenses"}}}, }, }, }, }, } collection := client.Database("你的库名").Collection("你的集合名") _, err = collection.UpdateOne(context.TODO(), filter, update) return err }
内容的提问来源于stack exchange,提问作者gelerum
相关产品推荐
相关产品推荐

