Golang中MongoDB聚合函数的使用与实践

Golang中MongoDB聚合函数的使用与实践 我有基本的代码来删除MongoDB集合中的重复项

db.myCollection.aggregate([
 {
        "$group": {
            "_id": {"key": "$key"},
            "dups": {"$push": "$_id"},
            "count": { "$sum": 1 }
        }
    },
    {
         "$match": {
             "count": { "$gt": 1 }
         }
     }
    ]).forEach(function(doc){
        doc.dups.shift();
        db.myCollection.remove({
            "_id" : {"$in": doc.dups}
        });
    })

但是如何使用mgo库来执行所有这些操作?

GitHub go-mgo/mgo

头像

go-mgo/mgo

mgo - Go语言的MongoDB驱动。未维护 - 见下文

我见过使用Pipe进行排序和分组的例子,但是如何在mgo中使用"forEach"函数 有人执行过类似这样的操作吗? 谢谢!


更多关于Golang中MongoDB聚合函数的使用与实践的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中MongoDB聚合函数的使用与实践的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中使用mgo库执行MongoDB聚合操作并处理重复数据删除时,需要使用Pipe方法构建聚合管道,然后通过迭代结果集来执行删除操作。以下是完整的示例代码:

package main

import (
    "fmt"
    "log"

    "gopkg.in/mgo.v2"
    "gopkg.in/mgo.v2/bson"
)

type DupResult struct {
    ID    bson.M   `bson:"_id"`
    Dups  []string `bson:"dups"`
    Count int      `bson:"count"`
}

func main() {
    session, err := mgo.Dial("localhost")
    if err != nil {
        log.Fatal(err)
    }
    defer session.Close()

    collection := session.DB("test").C("myCollection")

    pipe := collection.Pipe([]bson.M{
        {
            "$group": bson.M{
                "_id":   bson.M{"key": "$key"},
                "dups":  bson.M{"$push": "$_id"},
                "count": bson.M{"$sum": 1},
            },
        },
        {
            "$match": bson.M{
                "count": bson.M{"$gt": 1},
            },
        },
    })

    iter := pipe.Iter()
    var result DupResult
    
    for iter.Next(&result) {
        if len(result.Dups) > 1 {
            // 移除第一个元素,保留一个副本
            dupsToRemove := result.Dups[1:]
            
            // 构建删除条件
            removeCondition := bson.M{"_id": bson.M{"$in": dupsToRemove}}
            
            // 执行删除操作
            changeInfo, err := collection.RemoveAll(removeCondition)
            if err != nil {
                log.Printf("删除失败: %v", err)
                continue
            }
            
            fmt.Printf("删除了 %d 个重复文档\n", changeInfo.Removed)
        }
    }
    
    if err := iter.Close(); err != nil {
        log.Fatal(err)
    }
}

关键点说明:

  1. 使用collection.Pipe()构建聚合管道,参数为[]bson.M切片
  2. 聚合阶段使用bson.M类型构建,语法与MongoDB原生聚合操作一致
  3. 通过pipe.Iter()获取迭代器来遍历聚合结果
  4. 定义结构体DupResult来映射聚合结果的字段
  5. 在迭代过程中,使用result.Dups[1:]跳过第一个文档ID,删除其余重复项
  6. 使用collection.RemoveAll()执行批量删除操作

这个实现完全替代了MongoDB shell中的forEach功能,通过Go的迭代器模式处理聚合结果并执行相应的删除操作。

回到顶部