Het resultaat van een MongoDB find() is altijd een lijst met documenten. Dus als u een lijst met waarden wilt, moet u deze handmatig converteren, net zoals u deed.
Een aangepast type gebruiken (afgeleid van string )
Merk ook op dat als u uw eigen type zou maken (afgeleid van string ), kunt u de niet-marshaling-logica overschrijven en alleen de username "extraheren" uit het document.
Zo zou het eruit kunnen zien:
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
}
En dan de gebruikersnamen opvragen in een segment:
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)
Merk op dat []Username is niet hetzelfde als []string , dus dit kan al dan niet voldoende zijn voor u. Mocht u een gebruikersnaam nodig hebben als waarde van string in plaats van Username bij het verwerken van het resultaat kunt u eenvoudig een Username . converteren naar string .
Gebruik Query.Iter()
Een andere manier om het kopiëren van de slice te voorkomen, is door Query.Iter()
, herhaal de resultaten en extraheer en bewaar de username handmatig, op dezelfde manier als de bovenstaande aangepaste unmarshaling-logica.
Zo zou het eruit kunnen zien:
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)