使用MongoDB和Golang查找具有聚合和查找的重复项

时间:2018-04-20 11:40:44

标签: mongodb go

我需要找到与MongoDB和Golang进行聚合和查找的重复项。 这是我的Event结构。

// Event describes the model of an Event
type Event struct {
    ID            string      `bson:"_id" json:"_id" valid:"alphanum,printableascii"`
    OldID         string      `bson:"old_id" json:"old_id" valid:"alphanum,printableascii"`
    ParentID      string      `bson:"_parent_id" json:"_parent_id" valid:"alphanum,printableascii"`
    Name          string      `bson:"name" json:"name"`
    Content       string      `bson:"content" json:"content"`
    Slug          string      `bson:"slug" json:"slug"`
    LocationID    string      `bson:"_location_id" json:"_location_id"`
    Price         string      `bson:"price" json:"price"`
    CreatedBy     string      `bson:"created_by" json:"created_by"`
    CreatedAt     time.Time   `bson:"created_at" json:"created_at"`
    ModifiedAt    time.Time   `bson:"modified_at" json:"modified_at"`
}

以下是我已有的请求:

// Create the pipeline
    pipeline := []bson.M{
        bson.M{
            "$group": bson.M{
                "_id": bson.M{
                    "_location_id": "$_location_id",
                    "start_date":   "$start_date",
                },
                "docs":  bson.M{"$push": "$_id"},
                "count": bson.M{"$sum": 1},
            },
        },
        bson.M{
            "$match": bson.M{
                "count": bson.M{"$gt": 1.0},
            },
        },
    }

    // Do the request
    dupes := []bson.M{}
    err := session.DB(shared.DatabaseNamespace).C(dao.collection).Pipe(pipeline).All(&dupes)

事件不得具有相同的 start_date 和相同的 _location_id 。 这就是我能得到的:

/* 1 */
{
    "_id" : {
        "_location_id" : "4okPZllaoueYC3U2",
        "start_date" : ISODate("2018-04-22T18:00:00.000Z")
    },
    "count" : 2.0,
    "docs" : [ 
        "FFSC2sJcrWgj2FsU", 
        "lwHknTHFfVAzB8ui"
    ]
}

/* 2 */
{
    "_id" : {
        "_location_id" : "pC8rlLVao5c2CeBh",
        "start_date" : ISODate("2018-04-03T19:00:00.000Z")
    },
    "count" : 2.0,
    "docs" : [ 
        "jPRbkINiCExzh2tT", 
        "C8hx92QSZEl7HUIz"
    ]
}

很好,它有效,但.. 我想直接从Mongo获取一个我的Event类型的数组,如果可能的话,还有一个Event数组的数组:[][]*Event。 换句话说,是一个重复数组(在它们之间)。

例如:

// Pipeline
...

// Do the request
events := [][]*Events
err := session.DB(shared.DatabaseNamespace).C(dao.collection).Pipe(pipeline).All(&events)

或者,我是否需要使用Golang执行逻辑以实现我的需求?

我使用的库是:

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

仅供参考:无需关注_location_id,我在Golang逻辑中使用DTO查找。

编辑:如果我无法查找ID,我是否至少可以直接在结果中获取ID作为数组?例如:

[ 
    "jPRbkINiCExzh2tT", 
    "C8hx92QSZEl7HUIz"
]

这是我尝试添加到请求中的内容:{$out: "uniqueIds"}。但它没有用。

1 个答案:

答案 0 :(得分:0)

是的,您需要使用Golang执行逻辑以实现所需的功能。

您可以这样:

    type DublesAgregate struct {
    Id        IdStruct        `bson:"_id"`
    Docs      []bson.ObjectId `bson:"docs"`
    Count     string          `bson:"count,omitempty"`
}

type IdStruct struct {
    Location_id      string `bson:"_location_id,omitempty"`
    Start_date       string `bson:"start_date,omitempty"`
}

// Create the pipeline
    pipeline := []bson.M{
        bson.M{
            "$group": bson.M{
                "_id": bson.M{
                    "_location_id": "$_location_id",
                    "start_date":   "$start_date",
                },
                "docs":  bson.M{"$push": "$_id"},
                "count": bson.M{"$sum": 1},
            },
        },
        bson.M{
            "$match": bson.M{
                "count": bson.M{"$gt": 1.0},
            },
        },
    }

// Do the request
    dupes := []DublesAgregate{}
    err := session.DB(shared.DatabaseNamespace).C(dao.collection).Pipe(pipeline).All(&dupes)

// Get Docs slice
    result := []bson.ObjectId{}
    for _, group := range dupes {
        result = append(result, group.Docs...)
    }