Golang MongoDB不返回条件查询

时间:2019-01-31 01:49:14

标签: mongodb go mongodb-query

我具有使用官方mongo-go-driver(https://github.com/mongodb/mongo-go-driver

的功能。
func FindItemMongo(dataStruct interface{}, subItemKey string, collectionName string)(){
    fmt.Println("inside FindDataMongo in Controller")
    localDB := DB
    coll := localDB.Collection(collectionName)
    ctx, _ := context.WithTimeout(context.Background(), 5*time.Second)
    var searchData []uint8
    if subItemKey==""{
        fmt.Println("inside no key searchData")
        searchData, _ = bson.Marshal(bson.M{"data": dataStruct})
        fmt.Println("value of searchData")
        fmt.Println(searchData)
        fmt.Println("value of reflect type of searchData")
        fmt.Println(reflect.TypeOf(searchData))
    }else{
        reflectItem := reflect.ValueOf(dataStruct)
        subItem := reflectItem.FieldByName(subItemKey)
        subItemString := subItem.Interface().(string)
        searchData, _ =  bson.Marshal(bson.M{"data": bson.M{strings.ToLower(subItemKey): bson.M{"$eq": subItemString}}})
        fmt.Println("value of searchData")
        fmt.Println(searchData)
        fmt.Println("value of reflect type of searchData")
        fmt.Println(reflect.TypeOf(searchData))
    }
    cursor, err := coll.Find(ctx, searchData)
    if err != nil {
        log.Fatal(err)
    }
    defer cursor.Close(ctx)
    var returnBson []map[string]interface{}
    var result bson.M
    for cursor.Next(ctx) {
        err := cursor.Decode(&result)
        if err != nil { log.Fatal(err) }
        fmt.Println("value of found parsed")
        fmt.Println(result)
        returnBson = append(returnBson, result)
    }
}

哪个试图在数据库中查找与if语句有关的两个条件的数据。如果未定义subItemKey,则它将搜索与传入的struct完全匹配的内容;如果已定义键,则将仅使用$eq运算符在特定字段中搜索数据中的匹配项。

这适用于subItemKey为空的情况。像这样:

database.FindItemMongo(dataStruct, "", "users")

给予

api       | 1:36:55 app         | value of found parsed
api       | map[_id:ObjectID("8494398fsfd") data:map[email:qwer password:wer token:...]]

但是,如果我使用以下命令:

database.FindItemMongo(dataStruct, "Email", "users")

我什么也没得到。

我在else语句中定义searchData的方式不正确,我不确定是什么。有人看到出什么问题了吗?

编辑

我应该提到

的结果
    unmarshalledSearch := bson.M{"data": bson.M{strings.ToLower(subItemKey): bson.M{"$eq": subItemString}}}
    fmt.Println("value of unmarshalledSearch")
    fmt.Println(unmarshalledSearch)

api       | value of unmarshalledSearch
api       | map[data:map[email:map[$eq:qwer]]]

,与空字段查询返回的数据格式相同。这就是问题的症结所在-如果searchData似乎格式正确,为什么光标不返回任何结果?

3 个答案:

答案 0 :(得分:1)

我是Golang的新手,没有可以进行测试的环境,但是我认为您应该先遵循MongoDB Documentation中的示例并进行更改

var searchData []uint8
    searchData, _ =  bson.Marshal(bson.M{"data": bson.M{strings.ToLower(subItemKey): bson.M{"$eq": subItemString}}})

var searchData bson.D
    searchData = bson.D{{"data." + strings.ToLower(subItemKey), bson.D{{"$eq", subItemString}}}}

对于bison.D为空的情况,您绝对应该使用bison.M而不是subItemKey,因为如果字段顺序错误,则整个匹配的子文档将失败

对于搜索完全匹配的特殊情况,您可以使用简化格式

    searchData = bson.D{{"data." + strings.ToLower(subItemKey), subItemString}}

它可能无法解决您的问题,但至少遵循推荐的模式。

如果这不能解决您的搜索问题,请在您的帖子中添加您正在使用的Mongo驱动程序和数据库的版本,您希望检索的完整文档,dataStruct类型的声明以及初始化程序用于您传递的dataStruct

答案 1 :(得分:1)

给出结构Login

type Login struct {
    Email    string `json:"email"`
    Password string `json:"password"`
    Token    string `json:"token"`
}

假设你有数据作为

{data: {email: "name@example.com", password: "password", token: "token"}}

subItemKey为空白时,您的搜索与上面完全相同。但是,当您仅使用电子邮件进行搜索时,语法应为

{"data.email": "name@example.com"}

但是您的代码生成的搜索条件为

{"data":{"email":{"$eq":"name@example.com"}}}

要使其正常运行,请将行从

更改为

searchData, _ = bson.Marshal(bson.M{"data": bson.M{strings.ToLower(subItemKey): bson.M{"$eq": subItemString}}})

searchData, _ = bson.Marshal(bson.M{"data." + strings.ToLower(subItemKey): subItemString})

答案 2 :(得分:1)

我认为您想搜索一个嵌套属性,因此,您应该更改查询

此:

searchData, _ =  bson.Marshal(bson.M{"data": bson.M{strings.ToLower(subItemKey): bson.M{"$eq": subItemString}}})

收件人

nestedKey := fmt.Sprintf("data.%s", strings.ToLower(subItemKey))
searchData, _ = bson.Marshal(bson.M{nestedKey: subItemString})
相关问题