Golang中使用Mgo实现distinct查询和$in操作

Golang中使用Mgo实现distinct查询和$in操作 我在MongoDB的distinct查询中遇到了困难。

我可以编写Mongo shell命令,它能正常工作,但我不知道如何在Go代码中实现它。

这是我的Mongo shell命令:

db.getCollection('company_role_function').distinct("rolecode", {rolecode : {
   $in: ['DHBK_ROLE_01','DHBK_ROLE_03' ] },productid:'IOT_Platform'
})

这是我的Go代码:

  1. profile.go
type CompanyRoleFunction struct {
        Rolecode     string `json:"rolecode"`
        Productid    string `json:"productid"`
        Functioncode string `json:"functioncode"`
        Comid        string `json:"comid"`
     }
  1. repository.go
package repository
import "bitbucket.org/cloud-platform/vnpt-sso-usermgnt/model"
type IProfileRepository interface {
   FindRoleByUserProduct(string) (*model.CompanyRoleFunction, error)
}
  1. mongo_driver.go
package repository
import (
    "bitbucket.org/cloud-platform/vnpt-sso-usermgnt/model"
    "go.mongodb.org/mongo-driver/bson"
    "gopkg.in/mgo.v2"
)
type ProfileRepositoryMongo struct {
  db         *mgo.Database
  collection string
 }

 func NewProfileRepositoryMongo(db *mgo.Database, collection string) *ProfileRepositoryMongo {
    return &ProfileRepositoryMongo{
    db:         db,
    collection: collection,
   }
}
//我在这里遇到了问题
 func (r *ProfileRepositoryMongo) FindRoleByUserProduct(rolecode arr[]string)  (*model.CompanyRoleFunction, error) {
  var companyRoleFunction model.CompanyRoleFunction
   //我在这里遇到了问题
  err := r.db.C(r.collection).Find(bson.M{"username": username}).One(&companyRoleFunction)
   //我在这里遇到了问题
  if err != nil {
      return nil, err
   }
  return &companyRoleFunction, nil
 }

请帮助我。 谢谢。


更多关于Golang中使用Mgo实现distinct查询和$in操作的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang中使用Mgo实现distinct查询和$in操作的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go中使用Mgo实现distinct查询和$in操作,需要修改你的FindRoleByUserProduct方法。以下是正确的实现方式:

func (r *ProfileRepositoryMongo) FindRoleByUserProduct(rolecodes []string, productid string) ([]string, error) {
    // 构建查询条件
    query := bson.M{
        "rolecode": bson.M{"$in": rolecodes},
        "productid": productid,
    }
    
    // 执行distinct查询
    var result []string
    err := r.db.C(r.collection).Find(query).Distinct("rolecode", &result)
    
    if err != nil {
        return nil, err
    }
    
    return result, nil
}

如果你需要返回完整的文档而不仅仅是distinct值,可以使用以下方式:

func (r *ProfileRepositoryMongo) FindRoleByUserProduct(rolecodes []string, productid string) ([]model.CompanyRoleFunction, error) {
    // 构建查询条件
    query := bson.M{
        "rolecode": bson.M{"$in": rolecodes},
        "productid": productid,
    }
    
    // 执行查询
    var results []model.CompanyRoleFunction
    err := r.db.C(r.collection).Find(query).All(&results)
    
    if err != nil {
        return nil, err
    }
    
    return results, nil
}

接口定义也需要相应修改:

package repository
import "bitbucket.org/cloud-platform/vnpt-sso-usermgnt/model"

type IProfileRepository interface {
    FindRoleByUserProduct(rolecodes []string, productid string) ([]string, error)
    // 或者如果需要返回完整文档:
    // FindRoleByUserProduct(rolecodes []string, productid string) ([]model.CompanyRoleFunction, error)
}

使用示例:

// 调用示例
rolecodes := []string{"DHBK_ROLE_01", "DHBK_ROLE_03"}
productid := "IOT_Platform"

distinctRoles, err := repo.FindRoleByUserProduct(rolecodes, productid)
if err != nil {
    // 处理错误
}

// distinctRoles 将包含去重后的rolecode列表

如果你需要同时获取distinct值和对应的文档数量,可以使用聚合管道:

func (r *ProfileRepositoryMongo) FindRoleByUserProductWithCount(rolecodes []string, productid string) (map[string]int, error) {
    pipeline := []bson.M{
        {
            "$match": bson.M{
                "rolecode": bson.M{"$in": rolecodes},
                "productid": productid,
            },
        },
        {
            "$group": bson.M{
                "_id": "$rolecode",
                "count": bson.M{"$sum": 1},
            },
        },
    }
    
    var results []struct {
        Rolecode string `bson:"_id"`
        Count    int    `bson:"count"`
    }
    
    err := r.db.C(r.collection).Pipe(pipeline).All(&results)
    
    if err != nil {
        return nil, err
    }
    
    // 转换为map
    roleCounts := make(map[string]int)
    for _, result := range results {
        roleCounts[result.Rolecode] = result.Count
    }
    
    return roleCounts, nil
}
回到顶部