我具有使用官方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似乎格式正确,为什么光标不返回任何结果?
答案 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})