go-sonic/sonic/search.go
2019-03-25 20:34:14 +01:00

85 lines
1.9 KiB
Go

package sonic
import (
"fmt"
"strings"
)
type Searchable interface {
Query(collection, bucket, term string, limit, offset int) (results []string, err error)
Suggest(collection, bucket, word string, limit int) (results []string, err error)
}
type searchCommands string
const (
query searchCommands = "QUERY"
suggest searchCommands = "SUGGEST"
)
type SearchChannel struct {
*Driver
}
func NewSearch(host string, port int, password string) (Searchable, error) {
driver := &Driver{
Host: host,
Port: port,
Password: password,
Channel: Search,
}
err := driver.connect()
if err != nil {
return nil, err
}
return SearchChannel{
Driver: driver,
}, nil
}
func (s SearchChannel) Query(collection, bucket, term string, limit, offset int) (results []string, err error) {
err = s.write(fmt.Sprintf("%s %s %s \"%s\" LIMIT(%d) OFFSET(%d)", query, collection, bucket, term, limit, offset))
if err != nil {
return nil, err
}
// pending, should be PENDING ID_EVENT
_, err = s.read()
if err != nil {
return nil, err
}
// event query, should be EVENT QUERY ID_EVENT RESULT1 RESULT2 ...
read, err := s.read()
if err != nil {
return nil, err
}
return getSearchResults(read, string(query)), nil
}
func (s SearchChannel) Suggest(collection, bucket, word string, limit int) (results []string, err error) {
err = s.write(fmt.Sprintf("%s %s %s \"%s\" LIMIT(%d)", suggest, collection, bucket, word, limit))
if err != nil {
return nil, err
}
// pending, should be PENDING ID_EVENT
_, err = s.read()
if err != nil {
return nil, err
}
// event query, should be EVENT SUGGEST ID_EVENT RESULT1 RESULT2 ...
read, err := s.read()
if err != nil {
return nil, err
}
return getSearchResults(read, string(suggest)), nil
}
func getSearchResults(line string, eventType string) []string {
if strings.HasPrefix(line, "EVENT "+eventType) {
return strings.Split(line, " ")[3:]
}
return []string{}
}