Find()的结果有没有办法得到slice? [英] Is there a way to get slice as result of Find()?

查看:212
本文介绍了Find()的结果有没有办法得到slice?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  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 the username 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 of string instead of Username when processing the result, you can simply convert a Username to string.

Using Query.Iter()

Another way to avoid the slice copying would be to call Query.Iter(), iterate over the results and extract and store the username 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆