有没有更好的方法在mongo上创建动态匹配?

时间:2017-03-13 01:28:02

标签: mongodb go mgo

我正在创建一个显示所有类型数据的视图。目前我正在使用大量的if语句为true,并为所有不同类型的请求创建匹配参数。我真的不认为写出120可能,如果陈述是最好的方式..加上它变得难以保持。我希望有人可以指出正确的方向。这是我到目前为止所做的。

func GetAllHourly(dbsession *mgo.Session, year, month, day, site, size, network, region string, code int) (items []MassAggregation, err error) {
    defer dbsession.Close()
    var match bson.M
    if network == "openx3" {
        network = "openx"
    }

    group := bson.M{"$group": bson.M{"_id": bson.M{"aws_region": "$aws_region", "http_request_status": "$http_request_status", "hour": "$hour", "network": "$network", "site": "$site", "size": "$size", "zone": "$zone", "extra": "$extra"}, "total": bson.M{"$sum": "$count"}}}
    if site == "" && size == "" && network == "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day}}
    } else if site != "" && size == "" && network == "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site}}
    } else if site != "" && size != "" && network == "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size}}
    } else if site != "" && size != "" && network != "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}}}
    } else if site != "" && size != "" && network != "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region}}
    } else if site != "" && size != "" && network != "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region, "http_request_status": code}}
    } else if site == "" && size != "" && network == "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size}}
    } else if site == "" && size != "" && network != "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}}}
    } else if site == "" && size != "" && network != "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region}}
    } else if site == "" && size == "" && network != "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}}}
    } else if site == "" && size == "" && network != "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region}}
    } else if site == "" && size == "" && network != "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region, "http_request_status": code}}
    } else if site == "" && size == "" && network == "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "aws_region": region}}
    } else if site == "" && size == "" && network == "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "aws_region": region, "http_request_status": code}}
    } else if site == "" && size == "" && network == "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "http_request_status": code}}
    } else if site != "" && size == "" && network == "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "http_request_status": code}}
    } else if site != "" && size == "" && network == "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "aws_region": region}}
    } else if site != "" && size == "" && network != "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "network": &bson.RegEx{Pattern: network, Options: "i"}}}
    } else if site == "" && size != "" && network == "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "size": size, "http_request_status": code}}
    } else if site == "" && size != "" && network == "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "size": size, "aws_region": region}}
    } else if site == "" && size != "" && network != "" && region == "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "size": size, "network": &bson.RegEx{Pattern: network, Options: "i"}}}
    } else if site == "" && size == "" && network != "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "http_request_status": code}}
    } else if site == "" && size == "" && network != "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region}}
    } else if site != "" && size != "" && network != "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "size": size, "http_request_status": code}}
    } else if site != "" && size != "" && network == "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "site": site, "size": size, "http_request_status": code}}
    } else if site == "" && size != "" && network != "" && region == "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "size": size, "http_request_status": code}}
    } else if site != "" && size == "" && network != "" && region != "" && code == -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region, "site": site}}
    } else if site != "" && size == "" && network != "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region, "site": site, "http_request_status": code}}
    } else if site != "" && size == "" && network == "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "aws_region": region, "site": site, "http_request_status": code}}
    } else if site == "" && size != "" && network != "" && region != "" && code != -1 {
        match = bson.M{"$match": bson.M{"year": year, "month": month, "day": day, "network": &bson.RegEx{Pattern: network, Options: "i"}, "aws_region": region, "size": size, "http_request_status": code}}
    }

    operations := []bson.M{match, group}
    err = dbsession.DB("logs").C("prod").Pipe(operations).All(&items)
    return
}

你可以看到它不守规矩......但我还没有找到替代方案。我希望我找不到答案。

更新:我改变了一点方法。如果这是最好的方法,我仍然很好奇。

func GetAllHourly(dbsession *mgo.Session, year, month, day, site, size, network, region string, code int) (items []MassAggregation, err error) {
    defer dbsession.Close()
    matches := []bson.M{bson.M{"$match": bson.M{"year": year, "month": month, "day": day}}}
    if network == "openx3" {
        network = "openx"
    }

    if site != "" {
        matches = append(matches, bson.M{"$match": bson.M{"site": site}})
    }
    if size != "" {
        matches = append(matches, bson.M{"$match": bson.M{"size": size}})
    }
    if region != "" {
        matches = append(matches, bson.M{"$match": bson.M{"aws_region": region}})
    }
    if code != -1 {
        matches = append(matches, bson.M{"$match": bson.M{"http_request_status": code}})
    }
    if network != "" {
        matches = append(matches, bson.M{"$match": bson.M{"network": &bson.RegEx{Pattern: network, Options: "i"}}})
    }
    group := bson.M{"$group": bson.M{"_id": bson.M{"aws_region": "$aws_region", "http_request_status": "$http_request_status", "hour": "$hour", "network": "$network", "site": "$site", "size": "$size", "zone": "$zone", "extra": "$extra"}, "total": bson.M{"$sum": "$count"}}}
    var operations []bson.M
    for _, match := range matches {
        operations = append(operations, match)
    }
    operations = append(operations, group)
    err = dbsession.DB("logs").C("prod").Pipe(operations).All(&items)
    return
}

1 个答案:

答案 0 :(得分:1)

-TargetMigration只是bson.M{}的命名类型,您可以在文档中看到:http://godoc.org/labix.org/v2/mgo/bson#M

那么,为什么不用它作为字典来构建自定义查询?你的代码会少得多:

map[string]interface{}