WIP
This commit is contained in:
parent
fabde8de5f
commit
c580e44f1a
40
server.go
40
server.go
@ -44,7 +44,7 @@ import (
|
|||||||
|
|
||||||
var db *sql.DB
|
var db *sql.DB
|
||||||
|
|
||||||
func prepareColumn(steps int, minScore float64, allEntries, matchedEntries []record, features featureMap, modes modeMap, name string, col *column, wg *sync.WaitGroup) {
|
func prepareColumn(steps int, minScore float64, allEntries, matchedEntries []record, features map[string]float64, modes map[string]modeType, name string, col *column, wg *sync.WaitGroup) {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
*col = column{
|
*col = column{
|
||||||
@ -86,16 +86,16 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
request struct {
|
request struct {
|
||||||
Features featureMap `json:"features"`
|
Features map[string]float64 `json:"features"`
|
||||||
Geo *geoData `json:"geo"`
|
Geo *geoData `json:"geo"`
|
||||||
MaxResults int `json:"maxResults"`
|
MaxResults int `json:"maxResults"`
|
||||||
MinScore float64 `json:"minScore"`
|
MinScore float64 `json:"minScore"`
|
||||||
Modes map[string]string `json:"modes"`
|
Modes map[string]string `json:"modes"`
|
||||||
Profile featureMap `json:"profile"`
|
Profile map[string]float64 `json:"profile"`
|
||||||
Resolution int `json:"resolution"`
|
Resolution int `json:"resolution"`
|
||||||
SortAsc bool `json:"sortAsc"`
|
SortAsc bool `json:"sortAsc"`
|
||||||
SortKey string `json:"sortKey"`
|
SortKey string `json:"sortKey"`
|
||||||
WalkingDist float64 `json:"walkingDist"`
|
WalkingDist float64 `json:"walkingDist"`
|
||||||
}
|
}
|
||||||
|
|
||||||
response struct {
|
response struct {
|
||||||
@ -125,14 +125,10 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
|||||||
sorter := recordSorter{entries: matchedEntries, key: request.SortKey, ascending: request.SortAsc}
|
sorter := recordSorter{entries: matchedEntries, key: request.SortKey, ascending: request.SortAsc}
|
||||||
sorter.sort()
|
sorter.sort()
|
||||||
|
|
||||||
response.Columns = make(map[string]*column)
|
|
||||||
response.Count = len(matchedEntries)
|
|
||||||
response.MinScore = request.MinScore
|
|
||||||
response.Records = matchedEntries //[:request.MaxResults]
|
|
||||||
|
|
||||||
var wg sync.WaitGroup
|
var wg sync.WaitGroup
|
||||||
wg.Add(len(features))
|
wg.Add(len(features))
|
||||||
|
|
||||||
|
response.Columns = make(map[string]*column)
|
||||||
for name := range features {
|
for name := range features {
|
||||||
response.Columns[name] = new(column)
|
response.Columns[name] = new(column)
|
||||||
go prepareColumn(
|
go prepareColumn(
|
||||||
@ -149,8 +145,16 @@ func executeQuery(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
|
response.Count = len(matchedEntries)
|
||||||
|
response.MinScore = request.MinScore
|
||||||
response.ElapsedTime = time.Since(startTime).Nanoseconds()
|
response.ElapsedTime = time.Since(startTime).Nanoseconds()
|
||||||
|
|
||||||
|
if len(matchedEntries) > request.MaxResults {
|
||||||
|
response.Records = matchedEntries[:request.MaxResults]
|
||||||
|
} else {
|
||||||
|
response.Records = matchedEntries
|
||||||
|
}
|
||||||
|
|
||||||
js, err := json.Marshal(response)
|
js, err := json.Marshal(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
@ -279,8 +283,8 @@ func removeCategory(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
func accessReview(rw http.ResponseWriter, req *http.Request) {
|
func accessReview(rw http.ResponseWriter, req *http.Request) {
|
||||||
var request struct {
|
var request struct {
|
||||||
Id int `json:"id"`
|
Id int `json:"id"`
|
||||||
Profile featureMap `json:"profile"`
|
Profile map[string]float64 `json:"profile"`
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&request); err != nil {
|
||||||
|
18
types.go
18
types.go
@ -27,15 +27,18 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
|
|
||||||
type featureMap map[string]float64
|
|
||||||
type modeMap map[string]modeType
|
|
||||||
type modeType int
|
type modeType int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
modeTypeProd = iota + 1
|
modeTypeProd modeType = iota + 1
|
||||||
modeTypeDist
|
modeTypeDist
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type bracket struct {
|
||||||
|
Min float64 `json:"min"`
|
||||||
|
Max float64 `json:"max"`
|
||||||
|
}
|
||||||
|
|
||||||
type column struct {
|
type column struct {
|
||||||
Bracket bracket `json:"bracket"`
|
Bracket bracket `json:"bracket"`
|
||||||
Hints []projection `json:"hints"`
|
Hints []projection `json:"hints"`
|
||||||
@ -60,18 +63,13 @@ type record struct {
|
|||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Score float64 `json:"score"`
|
Score float64 `json:"score"`
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
features featureMap
|
features map[string]float64
|
||||||
geo geoData
|
geo geoData
|
||||||
}
|
}
|
||||||
|
|
||||||
type bracket struct {
|
|
||||||
Min float64 `json:"min"`
|
|
||||||
Max float64 `json:"max"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type queryContext struct {
|
type queryContext struct {
|
||||||
geo *geoData
|
geo *geoData
|
||||||
profile featureMap
|
profile map[string]float64
|
||||||
walkingDist float64
|
walkingDist float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
util.go
26
util.go
@ -31,8 +31,8 @@ import (
|
|||||||
"github.com/kellydunn/golang-geo"
|
"github.com/kellydunn/golang-geo"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fixFeatures(features featureMap) featureMap {
|
func fixFeatures(features map[string]float64) map[string]float64 {
|
||||||
fixedFeatures := featureMap{
|
fixedFeatures := map[string]float64{
|
||||||
"nearby": 0.0,
|
"nearby": 0.0,
|
||||||
"accessible": 0.0,
|
"accessible": 0.0,
|
||||||
"delicious": 0.0,
|
"delicious": 0.0,
|
||||||
@ -49,8 +49,8 @@ func fixFeatures(features featureMap) featureMap {
|
|||||||
return fixedFeatures
|
return fixedFeatures
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixModes(modes map[string]string) modeMap {
|
func fixModes(modes map[string]string) map[string]modeType {
|
||||||
fixedModes := modeMap{
|
fixedModes := map[string]modeType{
|
||||||
"nearby": modeTypeProd,
|
"nearby": modeTypeProd,
|
||||||
"accessible": modeTypeProd,
|
"accessible": modeTypeProd,
|
||||||
"delicious": modeTypeProd,
|
"delicious": modeTypeProd,
|
||||||
@ -69,7 +69,7 @@ func fixModes(modes map[string]string) modeMap {
|
|||||||
return fixedModes
|
return fixedModes
|
||||||
}
|
}
|
||||||
|
|
||||||
func similarity(features1 featureMap, features2 featureMap) float64 {
|
func similarity(features1 map[string]float64, features2 map[string]float64) float64 {
|
||||||
var result float64
|
var result float64
|
||||||
|
|
||||||
for key, value1 := range features1 {
|
for key, value1 := range features1 {
|
||||||
@ -81,7 +81,7 @@ func similarity(features1 featureMap, features2 featureMap) float64 {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func compare(features1 featureMap, features2 featureMap, modes modeMap) float64 {
|
func compare(features1 map[string]float64, features2 map[string]float64, modes map[string]modeType) float64 {
|
||||||
var result float64
|
var result float64
|
||||||
|
|
||||||
for key, value1 := range features1 {
|
for key, value1 := range features1 {
|
||||||
@ -100,7 +100,7 @@ func compare(features1 featureMap, features2 featureMap, modes modeMap) float64
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func walkMatches(entries []record, features featureMap, modes modeMap, minScore float64, callback func(record, float64)) {
|
func walkMatches(entries []record, features map[string]float64, modes map[string]modeType, minScore float64, callback func(record, float64)) {
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
if score := compare(features, entry.features, modes); score >= minScore {
|
if score := compare(features, entry.features, modes); score >= minScore {
|
||||||
callback(entry, score)
|
callback(entry, score)
|
||||||
@ -108,7 +108,7 @@ func walkMatches(entries []record, features featureMap, modes modeMap, minScore
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func statRecords(entries []record, features featureMap, modes modeMap, minScore float64) (float64, int) {
|
func statRecords(entries []record, features map[string]float64, modes map[string]modeType, minScore float64) (float64, int) {
|
||||||
var compatibility float64
|
var compatibility float64
|
||||||
var count int
|
var count int
|
||||||
|
|
||||||
@ -132,7 +132,7 @@ func stepRange(min, max float64, steps int, callback func(float64)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func findRecords(entries []record, features featureMap, modes modeMap, minScore float64) []record {
|
func findRecords(entries []record, features map[string]float64, modes map[string]modeType, minScore float64) []record {
|
||||||
var matchedEntries []record
|
var matchedEntries []record
|
||||||
|
|
||||||
walkMatches(entries, features, modes, minScore, func(entry record, score float64) {
|
walkMatches(entries, features, modes, minScore, func(entry record, score float64) {
|
||||||
@ -143,8 +143,8 @@ func findRecords(entries []record, features featureMap, modes modeMap, minScore
|
|||||||
return matchedEntries
|
return matchedEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
func project(entries []record, features featureMap, modes modeMap, featureName string, minScore float64, steps int) []projection {
|
func project(entries []record, features map[string]float64, modes map[string]modeType, featureName string, minScore float64, steps int) []projection {
|
||||||
sampleFeatures := make(featureMap)
|
sampleFeatures := make(map[string]float64)
|
||||||
for key, value := range features {
|
for key, value := range features {
|
||||||
sampleFeatures[key] = value
|
sampleFeatures[key] = value
|
||||||
}
|
}
|
||||||
@ -219,7 +219,7 @@ func computeRecordCompat(entry *record, context queryContext, wg *sync.WaitGroup
|
|||||||
}
|
}
|
||||||
defer groupRows.Close()
|
defer groupRows.Close()
|
||||||
|
|
||||||
recordProfile := make(featureMap)
|
recordProfile := make(map[string]float64)
|
||||||
for groupRows.Next() {
|
for groupRows.Next() {
|
||||||
var categoryId int
|
var categoryId int
|
||||||
var categoryValue float64
|
var categoryValue float64
|
||||||
@ -305,7 +305,7 @@ func getRecords(context queryContext) []record {
|
|||||||
geo: geoData{latitude, longitude},
|
geo: geoData{latitude, longitude},
|
||||||
Id: id}
|
Id: id}
|
||||||
|
|
||||||
entry.features = featureMap{
|
entry.features = map[string]float64{
|
||||||
"delicious": delicious,
|
"delicious": delicious,
|
||||||
"accommodating": accommodating,
|
"accommodating": accommodating,
|
||||||
"affordable": affordable,
|
"affordable": affordable,
|
||||||
|
Loading…
Reference in New Issue
Block a user