Skip to content

Instantly share code, notes, and snippets.

@icub3d
Created August 7, 2013 21:56
Show Gist options
  • Save icub3d/6179159 to your computer and use it in GitHub Desktop.
Save icub3d/6179159 to your computer and use it in GitHub Desktop.
An example of how to use mgo, the MongoDB driver for Go.
package main
import (
"bufio"
"fmt"
"labix.org/v2/mgo"
"labix.org/v2/mgo/bson"
"os"
"strings"
)
type Phone struct {
Type string
Number string
}
type Person struct {
Id bson.ObjectId `bson:"_id,omitempty"`
Handle string
Name string
Email string
Phones []Phone
}
func (p Person) String() string {
phones := ""
for _, phone := range p.Phones {
phones += fmt.Sprintf(", <Type: %s; Number %s>",
phone.Type, phone.Number)
}
if len(phones) > 0 {
phones = phones[2:]
}
return fmt.Sprintf(
"Handle: %s; Id: %s; Name: %s; E-mail: %s; Phones: %s",
p.Handle, p.Id, p.Name, p.Email, phones)
}
func main() {
// Initialize the mongodb connection.
session, err := mgo.Dial("localhost")
if err != nil {
fmt.Printf("initializing session:", err)
return
}
defer session.Close()
// Get our addressbook collection.
addressbook := session.DB("test").C("addressbook")
// Make sure we are indexing the handle. mgo convers the uppercased
// names to the lower case equivalent in the database. This index
// isn't going to help our find, but is an example of what to do
// when you want to queue off of something besides the Id.
addressbook.EnsureIndex(mgo.Index{
Key: []string{"handle"},
Unique: true,
})
scanner := bufio.NewScanner(os.Stdin)
quit := false
for !quit {
fmt.Print("mgo> ")
if !scanner.Scan() {
break
}
line := scanner.Text()
parts := strings.Split(line, " ")
cmd := parts[0]
args := parts[1:]
switch cmd {
// List and find are the same. They only differ in the filter.
case "list":
results(addressbook, nil)
case "find":
results(addressbook, bson.M{"handle": bson.M{"$regex": args[0], "$options": "i"}})
case "new":
p := newPerson(scanner)
if p == nil {
quit = true
break
}
// Create a new Id and Insert the information.
p.Id = bson.NewObjectId()
err = addressbook.Insert(p)
if err != nil {
fmt.Println("adding entry:", err)
}
case "quit":
quit = true
default:
fmt.Println("unrecognized command:", cmd, args)
}
}
if err := scanner.Err(); err != nil {
fmt.Println("reading stdin:", err)
}
}
func newPerson(scanner *bufio.Scanner) *Person {
fmt.Print("Name: ")
if !scanner.Scan() {
return nil
}
name := scanner.Text()
fmt.Print("Handle: ")
if !scanner.Scan() {
return nil
}
handle := scanner.Text()
fmt.Print("Email: ")
if !scanner.Scan() {
return nil
}
email := scanner.Text()
p := &Person{
Handle: handle,
Name: name,
Email: email,
}
for {
fmt.Print("Phone (blank to finish): ")
if !scanner.Scan() {
return nil
}
number := scanner.Text()
if number == "" {
break
}
fmt.Print("Type (home,work,mobile): ")
if !scanner.Scan() {
return nil
}
numberType := "home"
switch scanner.Text() {
case "work":
numberType = "work"
case "mobile":
numberType = "mobile"
case "home":
numberType = "home"
default:
fmt.Println("unrecognized type, using 'home'")
}
p.Phones = append(p.Phones, Phone{
Number: number,
Type: numberType,
})
}
return p
}
func results(addressbook *mgo.Collection, query bson.M) {
iter := addressbook.Find(query).Iter()
var p Person
for iter.Next(&p) {
fmt.Println(p)
}
if err := iter.Close(); err != nil {
fmt.Println("iterating results:", err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment