arnaucube
arnaucube/goRecommenderPublic Self-hosted repository
added initial items, implemented route newUser, starting recommendations, added tests.sh file
arnaucode idoctnef@openmailbox.org
Thu, 06 Jul 2017 09:32:53 +0200
commit

b403a740cffdedb0d6e2309b0849832cdca6957d

parent

e218286be00e26d28fd28f62a221454791150197

M README.md → README.md

@@ -8,3 +8,31 @@ Applies Machine Learning to perform recommendations:

- Random Forests - K Nearest Neighbours + + + + + + + +## Documentation + + - Add new user + +``` +POST /user +{ + id: "user1", + age: 30 +} +``` + + + - Get recommendations + +``` +GET /r/{userid}/{nrec} + +{userid}: is the userid +{nrec}: number of recommendations requested +```
D color.go

@@ -1,57 +0,0 @@

-package main - -import "fmt" - -//Color struct, defines the color -type Color struct{} - -var c Color - -//DarkGray color -func (c Color) DarkGray(t string) { - fmt.Print("\x1b[30;1m") //dark gray - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Red color -func (c Color) Red(t string) { - fmt.Print("\x1b[31;1m") //red - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Green color -func (c Color) Green(t string) { - fmt.Print("\x1b[32;1m") //green - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Yellow color -func (c Color) Yellow(t string) { - fmt.Print("\x1b[33;1m") //yellow - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Blue color -func (c Color) Blue(t string) { - fmt.Print("\x1b[34;1m") //blue - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Purple color -func (c Color) Purple(t string) { - fmt.Print("\x1b[35;1m") //purple - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -} - -//Cyan color -func (c Color) Cyan(t string) { - fmt.Print("\x1b[36;1m") //cyan - fmt.Println(t) - fmt.Print("\x1b[0m") //defaultColor -}
A itemSamples.data

@@ -0,0 +1,5 @@

+item1 +item2 +item3 +item4 +item5
M main.go → main.go

@@ -5,17 +5,29 @@ "fmt"

"log" "net/http" + mgo "gopkg.in/mgo.v2" + "github.com/fatih/color" ) +var userCollection *mgo.Collection +var itemCollection *mgo.Collection + func main() { fmt.Println("starting") //mongodb start readMongodbConfig("./mongodbConfig.json") - c := connectMongodb() - fmt.Println(c) + session, err := getSession() + check(err) + userCollection = getCollection(session, "users") + itemCollection = getCollection(session, "items") color.Green("mongodb connected") + + //read items dataset + itemsDataset := readDataset("./itemSamples.data", "\n", ",") + items := getItemsFromDataset(itemsDataset) + datasetToMongodbIfNotExist(itemCollection, items) //http server start readServerConfig("./serverConfig.json")
M mongodb.go → mongodb.go

@@ -7,13 +7,13 @@ "io/ioutil"

"log" mgo "gopkg.in/mgo.v2" + "gopkg.in/mgo.v2/bson" ) //MongoConfig stores the configuration of mongodb to connect type MongoConfig struct { - Ip string `json:"ip"` - Database string `json:"database"` - Collection string `json:"collection"` + Ip string `json:"ip"` + Database string `json:"database"` } var mongoConfig MongoConfig

@@ -42,17 +42,9 @@ session.SetMode(mgo.Monotonic, true)

return session, err } -func getCollection(session *mgo.Session) *mgo.Collection { +func getCollection(session *mgo.Session, collection string) *mgo.Collection { - c := session.DB(mongoConfig.Database).C(mongoConfig.Collection) - return c -} -func connectMongodb() *mgo.Collection { - session, err := getSession() - if err != nil { - log.Fatal(err) - } - c := getCollection(session) + c := session.DB(mongoConfig.Database).C(collection) return c }

@@ -70,3 +62,39 @@ log.Fatal(err)

} } + +func saveItem(c *mgo.Collection, item ItemModel) { + //first, check if the item already exists + result := ItemModel{} + err := c.Find(bson.M{"id": item.ID}).One(&result) + if err != nil { + //item not found, so let's add a new entry + err = c.Insert(item) + check(err) + } else { + /*result.Data = append(result.Data, dataEntry) + err = c.Update(bson.M{"id": dataEntry.ContratoCOD}, result) + if err != nil { + log.Fatal(err) + }*/ + } + +} + +func saveUser(c *mgo.Collection, user UserModel) { + //first, check if the item already exists + result := UserModel{} + err := c.Find(bson.M{"id": user.ID}).One(&result) + if err != nil { + //item not found, so let's add a new entry + err = c.Insert(user) + check(err) + } else { + /*result.Data = append(result.Data, dataEntry) + err = c.Update(bson.M{"id": dataEntry.ContratoCOD}, result) + if err != nil { + log.Fatal(err) + }*/ + } + +}
M mongodbConfig.json → mongodbConfig.json

@@ -1,5 +1,4 @@

{ "ip": "127.0.0.1", - "database": "goRecommend", - "collection": "userHistory" + "database": "goRecommend" }
M mongodbModels.go → mongodbModels.go

@@ -1,6 +1,15 @@

package main type UserModel struct { - Userid string - History []string + ID string `json:"id"` + Age int `json:",string"` + Actions []string +} +type ItemModel struct { + ID string + TRecommended int + TActed int } + +var scores []float64 +var ranking []ItemModel
A readItemSamples.go

@@ -0,0 +1,43 @@

+package main + +import ( + "fmt" + "io/ioutil" + "strings" + + mgo "gopkg.in/mgo.v2" +) + +func readDataset(path string, lineSeparation string, valueSeparation string) [][]string { + var dataset [][]string + b, err := ioutil.ReadFile(path) + check(err) + str := string(b) + str = strings.Replace(str, "\r", "", -1) + lines := strings.Split(str, lineSeparation) + for _, v1 := range lines { + params := strings.Split(v1, valueSeparation) + var datasetLine []string + for _, v2 := range params { + datasetLine = append(datasetLine, v2) + } + dataset = append(dataset, datasetLine) + } + return dataset +} +func getItemsFromDataset(dataset [][]string) []ItemModel { + var items []ItemModel + for _, v := range dataset { + var newItem ItemModel + newItem.ID = v[0] + items = append(items, newItem) + } + return items +} + +func datasetToMongodbIfNotExist(c *mgo.Collection, items []ItemModel) { + fmt.Println(items) + for _, item := range items { + saveItem(c, item) + } +}
M serverRoutes.go → serverRoutes.go

@@ -1,8 +1,11 @@

package main import ( + "encoding/json" "fmt" "net/http" + + "github.com/gorilla/mux" ) type Routes []Route

@@ -15,18 +18,45 @@ "/",

Index, }, Route{ - "NewImage", + "Recommendations", + "GET", + "/r/{userid}/{nrec}", + Recommendations, + }, + Route{ + "NewUser", "POST", - "/image", - NewImage, + "/user", + NewUser, }, } //ROUTES func Index(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "send images to the /image path") + fmt.Fprintln(w, "ask for recommendations in /r") } -func NewImage(w http.ResponseWriter, r *http.Request) { - fmt.Fprintln(w, "response") + +func NewUser(w http.ResponseWriter, r *http.Request) { + decoder := json.NewDecoder(r.Body) + var newUser UserModel + err := decoder.Decode(&newUser) + check(err) + defer r.Body.Close() + + saveUser(userCollection, newUser) + + fmt.Println(newUser) + fmt.Fprintln(w, "new user added: ", newUser.ID) +} +func Recommendations(w http.ResponseWriter, r *http.Request) { + vars := mux.Vars(r) + userid := vars["userid"] + nrec := vars["nrec"] + fmt.Println(userid) + fmt.Println(nrec) + + //now, get recommendations + + fmt.Fprintln(w, "recommendations") }
A tests.sh

@@ -0,0 +1,15 @@

+echo "------------------" +echo "[Adding new users]" + +echo http http://127.0.0.1:3056/user id="user1" age=23 +http http://127.0.0.1:3056/user id="user1" age=23 + +echo http http://127.0.0.1:3056/user id="user2" age=32 +http http://127.0.0.1:3056/user id="user2" age=32 + +echo "------------------" + +echo "[Getting recommendations for user]" + +echo http http://127.0.0.1:3056/user1/3 +http http://127.0.0.1:3056/r/user1/3