Find()的结果有没有办法得到slice? [英] Is there a way to get slice as result of Find()?
问题描述
sess:= mongodb.DB(mybase)。C(mycollection )
var users [] struct {
用户名字符串`bson:username`
}
err = sess.Find(nil).Select(bson。所有(&用户)
如果err!= nil {
fmt.Println(err)
} $ b $ {$ username}:1,_id:0})。 b
var myUsers [] string
for _,user:= range users {
myUsers = append(myUsers,user.Username)
}
有没有一种更有效的方法可以直接从Find(或另一个搜索函数)获取用户名的切片,而不需要结构和范围循环?解决方案MongoDB find()
的结果始终是文档列表。因此,如果你想要一个值列表,你必须像你一样手动转换。
使用自定义类型(从
string
)
另请注意,如果您要创建自己的类型(从
string
派生) ,你可以重写它的反编组逻辑,并从文档中提取出username
。
它可能看起来像:
type用户名字符串
func(u *用户名)SetBSON(raw bson .Raw)(err error){
doc:= bson.M {}
if err = raw.Unmarshal(& doc); err!= nil {
return
}
* u =用户名(doc [username]。(string))
return
}
然后将用户名查询到切片:
c:= mongodb.DB(mybase)。C(mycollection)//获取集合
var uns []用户名
err = c。 Find(nil).Select(bson.M {username:1,_id:0})。所有(& uns)
if err!= nil {
fmt.Println(err )
}
fmt.Println(uns)
请注意
[]用户名
与[]字符串
不同,所以这可能会或可能不足以满足您的需求。如果您在处理结果时需要用户名作为string
而不是Username
的值,则可以简单地将一个用户名用户名
至字符串
。
使用
Query.Iter()
避免切片复制的另一种方法是调用
Query.Iter()
,迭代结果并提取并手动存储用户名
,类似于上述自定义解组逻辑的功能。
这是它的外观如:
var uns [] string
it:= c.Find(nil).Select(bson.M {username:1,_id:0})。Iter()
推迟it.Close()
for doc:=(bson.M {}); it.Next(安培; DOC); {
uns = append(uns,doc [username]。(string))
}
如果err:= it.Err(); err!= nil {
fmt.Println(err)
}
fmt.Println(uns)
Now I'm doing:
sess := mongodb.DB("mybase").C("mycollection") var users []struct { Username string `bson:"username"` } err = sess.Find(nil).Select(bson.M{"username": 1, "_id": 0}).All(&users) if err != nil { fmt.Println(err) } var myUsers []string for _, user := range users{ myUsers = append(myUsers, user.Username) }
Is there a more effective way to get slice with usernames from Find (or another search function) directly, without struct and range loop?
解决方案The result of a MongoDB
find()
is always a list of documents. So if you want a list of values, you have to convert it manually just as you did.Using a custom type (derived from
string
)Also note that if you would create your own type (derived from
string
), you could override its unmarshaling logic, and "extract" just theusername
from the document.This is how it could look like:
type Username string func (u *Username) SetBSON(raw bson.Raw) (err error) { doc := bson.M{} if err = raw.Unmarshal(&doc); err != nil { return } *u = Username(doc["username"].(string)) return }
And then querying the usernames into a slice:
c := mongodb.DB("mybase").C("mycollection") // Obtain collection var uns []Username err = c.Find(nil).Select(bson.M{"username": 1, "_id": 0}).All(&uns) if err != nil { fmt.Println(err) } fmt.Println(uns)
Note that
[]Username
is not the same as[]string
, so this may or may not be sufficient to you. Should you need a user name as a value ofstring
instead ofUsername
when processing the result, you can simply convert aUsername
tostring
.Using
Query.Iter()
Another way to avoid the slice copying would be to call
Query.Iter()
, iterate over the results and extract and store theusername
manually, similarly how the above custom unmarshaling logic does.This is how it could look like:
var uns []string it := c.Find(nil).Select(bson.M{"username": 1, "_id": 0}).Iter() defer it.Close() for doc := (bson.M{}); it.Next(&doc); { uns = append(uns, doc["username"].(string)) } if err := it.Err(); err != nil { fmt.Println(err) } fmt.Println(uns)
这篇关于Find()的结果有没有办法得到slice?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文