Create Database
Create a database with the name is learn_mongodb_golang. This database have a collection: Product collection.
/* Create learn_mongodb_golang database */
use learn_mongodb_golang
/* Create Product collection */
db.createCollection('product');
/* Dumping data for `product` collection */
db.getCollection('product').insert({
"name" : "Mobile 1",
"price" : 45.0,
"quantity" : 4,
"status" : true,
"date" : ISODate("2016-10-20T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa45711668"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 1"
},
"colors" : [
"red",
"green",
"blue"
]
});
db.getCollection('product').insert({
"name" : "Mobile 2",
"price" : 12.0,
"quantity" : 7,
"status" : true,
"date" : ISODate("2017-11-14T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa45711668"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 2"
},
"colors" : [
"yellow",
"green"
]
});
db.getCollection('product').insert({
"name" : "Mobile 3",
"price" : 28.0,
"quantity" : 8,
"status" : true,
"date" : ISODate("2017-11-20T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa45711668"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 3"
},
"colors" : [
"black",
"blue"
]
});
db.getCollection('product').insert({
"name" : "Laptop 1",
"price" : 39.0,
"quantity" : 12,
"status" : false,
"date" : ISODate("2017-12-26T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa45711669"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 1"
},
"colors" : [
"blue"
]
});
db.getCollection('product').insert({
"name" : "Laptop 2",
"price" : 86.0,
"quantity" : 23,
"status" : true,
"date" : ISODate("2017-03-11T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa45711669"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 1"
},
"colors" : [
"blue",
"yellow"
]
});
db.getCollection('product').insert({
"name" : "Tivi 1",
"price" : 22.0,
"quantity" : 7,
"status" : true,
"date" : ISODate("2017-06-26T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa4571166a"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 1"
},
"colors" : [
"blue",
"white",
"black"
]
});
db.getCollection('product').insert({
"name" : "Tivi 2",
"price" : 86.0,
"quantity" : 23,
"status" : false,
"date" : ISODate("2017-09-24T00:00:00.000Z"),
"categoryId" : ObjectId("5a30de130867edfa4571166a"),
"brand" : {
"_id" : new ObjectId(),
"name" : "brand 3"
},
"colors" : [
"red",
"green"
]
});
Installing Libraries
Install MGO library as below:
go get gopkg.in/mgo.v2
Configuration
In src folder, create new folder named config. In this folder, create new file named config.go, this file is used to connect to mongodb database:
package config
import (
mgo "gopkg.in/mgo.v2"
)
func GetMongoDB() (*mgo.Database, error) {
host := "mongodb://localhost:27017"
dbName := "learn_mongodb_golang"
session, err := mgo.Dial(host)
if err != nil {
return nil, err
}
db := session.DB(dbName)
return db, nil
}
Entity Classes
Create new folder named entities. In this folder, create new go files as below:
Brand Entity
In entities folder, create new go file named brand_entity.go as below:
package entities
import (
"fmt"
"gopkg.in/mgo.v2/bson"
)
type Brand struct {
Id bson.ObjectId `bson:"_id"`
Name string `bson:"name"`
}
func (this Brand) ToString() string {
result := fmt.Sprintf("\nbrand id: %s", this.Id.Hex())
result = result + fmt.Sprintf("\nbrand name: %s", this.Name)
return result
}
Product Entity
In entities folder, create new go file named product_entity.go as below:
package entities
import (
"fmt"
"strings"
"time"
"gopkg.in/mgo.v2/bson"
)
type Product struct {
Id bson.ObjectId `bson:"_id"`
Name string `bson:"name"`
Price float64 `bson:"price"`
Quantity int64 `bson:"quantity"`
Status bool `bson:"status"`
Date time.Time `bson:"date"`
CategoryId bson.ObjectId `bson:"categoryId"`
Brand Brand `bson:"brand"`
Colors []string `bson:"colors"`
}
func (this Product) ToString() string {
result := fmt.Sprintf("id: %s", this.Id.Hex())
result = result + fmt.Sprintf("\nname: %s", this.Name)
result = result + fmt.Sprintf("\nprice: %0.1f", this.Price)
result = result + fmt.Sprintf("\nquantity: %d", this.Quantity)
result = result + fmt.Sprintf("\nstatus: %t", this.Status)
result = result + fmt.Sprintf("\ndate: %s", this.Date.Format("2006-01-02"))
result = result + fmt.Sprintf("\ncategory id: %s", this.Category.Hex())
result = result + this.Brand.ToString()
result = result + fmt.Sprintf("\ncolors: %s", strings.Join(this.Colors, ", "))
return result
}
CategoryGroup Entity
In entities folder, create new go file named category_group_entity.go as below:
package entities
import (
"fmt"
"gopkg.in/mgo.v2/bson"
)
type CategoryGroup struct {
CategoryId bson.ObjectId
CountProduct int
SumQuantity int64
MinPrice float64
MaxPrice float64
AvgPrice float64
}
func (this CategoryGroup) ToString() string {
result := fmt.Sprintf("Category Id: %s\n", this.CategoryId.Hex())
result = result + fmt.Sprintf("Count Product: %d\n", this.CountProduct)
result = result + fmt.Sprintf("Sum Quantities: %d\n", this.SumQuantity)
result = result + fmt.Sprintf("Min Price: %0.1f\n", this.MinPrice)
result = result + fmt.Sprintf("Max Price: %0.1f", this.MaxPrice)
return result
}
Models
In src folder, create new folder named models. In models folder, create new file named product_model.go. This file contains methods to interact with the database.
package models
import (
"config"
"entities"
"reflect"
"gopkg.in/mgo.v2/bson"
)
type ProductModel struct {
}
func (this ProductModel) GroupByAndHavingWithCategories() ([]entities.CategoryGroup, error) {
db, err := config.GetMongoDB()
if err != nil {
return nil, err
} else {
pipeline := []bson.M{
{
"$group": bson.M{
"_id": "$categoryId",
"countProduct": bson.M{"$sum": 1},
"sumQuantity": bson.M{"$sum": "$quantity"},
"maxPrice": bson.M{"$max": "$price"},
"minPrice": bson.M{"$min": "$price"},
"avgPrice": bson.M{"$avg": "$price"},
},
},
{
"$match": bson.M{
"sumQuantity": bson.M{"$gt": 20},
},
},
}
result := []bson.M{}
err = db.C("product").Pipe(pipeline).All(&result)
var categoryGroups []entities.CategoryGroup
for i := 0; i < len(result); i++ {
var sumQ int64
switch reflect.TypeOf(result[i]["sumQuantity"]).Name() {
case "int":
sumQ = int64(result[i]["sumQuantity"].(int))
case "int64":
sumQ = result[i]["sumQuantity"].(int64)
}
categoryGroup := entities.CategoryGroup{
CategoryId: result[i]["_id"].(bson.ObjectId),
CountProduct: result[i]["countProduct"].(int),
SumQuantity: sumQ,
MinPrice: result[i]["minPrice"].(float64),
MaxPrice: result[i]["maxPrice"].(float64),
AvgPrice: result[i]["avgPrice"].(float64),
}
categoryGroups = append(categoryGroups, categoryGroup)
}
return categoryGroups, nil
}
}
Structure of Project
Run Application
In src folder, create new file named main.go and use command go run main.go run application:
package main
import (
"fmt"
"models"
)
func main() {
var productModel models.ProductModel
categoryGroups, _ := productModel.GroupByAndHavingWithCategories()
for _, categoryGroup := range categoryGroups {
fmt.Println(categoryGroup.ToString())
fmt.Println("----------------------------------")
}
}
Output
Category Id: 5a30de130867edfa4571166a
Count Product: 2
Sum Quantities: 30
Min Price: 22.0
Max Price: 86.0
----------------------------------
Category Id: 5a30de130867edfa45711669
Count Product: 2
Sum Quantities: 35
Min Price: 39.0
Max Price: 86.0
----------------------------------