Merge pull request #14 from acasas/fields_struct
Support for passing a struct to a document instead of map[string]interface{}
This commit is contained in:
commit
7e772ee99b
@ -8,13 +8,35 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/belogik/goes"
|
"github.com/belogik/goes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ES_HOST = "localhost"
|
||||||
|
ES_PORT = "9200"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getConnection() (conn *goes.Connection) {
|
||||||
|
h := os.Getenv("TEST_ELASTICSEARCH_HOST")
|
||||||
|
if h == "" {
|
||||||
|
h = ES_HOST
|
||||||
|
}
|
||||||
|
|
||||||
|
p := os.Getenv("TEST_ELASTICSEARCH_PORT")
|
||||||
|
if p == "" {
|
||||||
|
p = ES_PORT
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = goes.NewConnection(h, p)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func ExampleConnection_CreateIndex() {
|
func ExampleConnection_CreateIndex() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
|
|
||||||
mapping := map[string]interface{}{
|
mapping := map[string]interface{}{
|
||||||
"settings": map[string]interface{}{
|
"settings": map[string]interface{}{
|
||||||
@ -43,7 +65,7 @@ func ExampleConnection_CreateIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleConnection_DeleteIndex() {
|
func ExampleConnection_DeleteIndex() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
resp, err := conn.DeleteIndex("yourinde")
|
resp, err := conn.DeleteIndex("yourinde")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -54,7 +76,7 @@ func ExampleConnection_DeleteIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleConnection_RefreshIndex() {
|
func ExampleConnection_RefreshIndex() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
resp, err := conn.RefreshIndex("yourindex")
|
resp, err := conn.RefreshIndex("yourindex")
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -65,7 +87,7 @@ func ExampleConnection_RefreshIndex() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleConnection_Search() {
|
func ExampleConnection_Search() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
|
|
||||||
var query = map[string]interface{}{
|
var query = map[string]interface{}{
|
||||||
"query": map[string]interface{}{
|
"query": map[string]interface{}{
|
||||||
@ -102,7 +124,7 @@ func ExampleConnection_Search() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleConnection_Index() {
|
func ExampleConnection_Index() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
|
|
||||||
d := goes.Document{
|
d := goes.Document{
|
||||||
Index: "twitter",
|
Index: "twitter",
|
||||||
@ -126,7 +148,7 @@ func ExampleConnection_Index() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ExampleConnection_Delete() {
|
func ExampleConnection_Delete() {
|
||||||
conn := goes.NewConnection("localhost", "9200")
|
conn := getConnection()
|
||||||
|
|
||||||
//[create index, index document ...]
|
//[create index, index document ...]
|
||||||
|
|
||||||
@ -154,7 +176,8 @@ func ExampleConnectionOverrideHttpClient() {
|
|||||||
cl := &http.Client{
|
cl := &http.Client{
|
||||||
Transport: tr,
|
Transport: tr,
|
||||||
}
|
}
|
||||||
conn := goes.NewConnection("localhost", "9200").WithClient(cl)
|
conn := getConnection()
|
||||||
|
conn.WithClient(cl)
|
||||||
|
|
||||||
fmt.Printf("%v\n", conn.Client)
|
fmt.Printf("%v\n", conn.Client)
|
||||||
}
|
}
|
||||||
|
23
goes.go
23
goes.go
@ -13,6 +13,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -139,13 +140,25 @@ func (c *Connection) BulkSend(documents []Document) (Response, error) {
|
|||||||
bulkData[i] = action
|
bulkData[i] = action
|
||||||
i++
|
i++
|
||||||
|
|
||||||
if len(doc.Fields) > 0 {
|
if doc.Fields != nil {
|
||||||
fields := make(map[string]interface{}, len(doc.Fields))
|
if docFields, ok := doc.Fields.(map[string]interface{}); ok {
|
||||||
for fieldName, fieldValue := range doc.Fields {
|
if len(docFields) == 0 {
|
||||||
fields[fieldName] = fieldValue
|
continue
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
typeOfFields := reflect.TypeOf(doc.Fields)
|
||||||
|
if typeOfFields.Kind() == reflect.Ptr {
|
||||||
|
typeOfFields = typeOfFields.Elem()
|
||||||
|
}
|
||||||
|
if typeOfFields.Kind() != reflect.Struct {
|
||||||
|
return Response{}, fmt.Errorf("Document fields not in struct or map[string]interface{} format")
|
||||||
|
}
|
||||||
|
if typeOfFields.NumField() == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sources, err := json.Marshal(fields)
|
sources, err := json.Marshal(doc.Fields)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Response{}, err
|
return Response{}, err
|
||||||
}
|
}
|
||||||
|
93
goes_test.go
93
goes_test.go
@ -193,7 +193,7 @@ func (s *GoesTestSuite) TestBulkSend(c *C) {
|
|||||||
docType := "tweet"
|
docType := "tweet"
|
||||||
|
|
||||||
tweets := []Document{
|
tweets := []Document{
|
||||||
Document{
|
{
|
||||||
Id: "123",
|
Id: "123",
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -204,7 +204,7 @@ func (s *GoesTestSuite) TestBulkSend(c *C) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -263,13 +263,13 @@ func (s *GoesTestSuite) TestBulkSend(c *C) {
|
|||||||
c.Assert(checked, Equals, 2)
|
c.Assert(checked, Equals, 2)
|
||||||
|
|
||||||
docToDelete := []Document{
|
docToDelete := []Document{
|
||||||
Document{
|
{
|
||||||
Id: "123",
|
Id: "123",
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
BulkCommand: BULK_COMMAND_DELETE,
|
BulkCommand: BULK_COMMAND_DELETE,
|
||||||
},
|
},
|
||||||
Document{
|
{
|
||||||
Id: extraDocId,
|
Id: extraDocId,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -321,6 +321,73 @@ func (s *GoesTestSuite) TestStats(c *C) {
|
|||||||
c.Assert(err, IsNil)
|
c.Assert(err, IsNil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GoesTestSuite) TestIndexWithFieldsInStruct(c *C) {
|
||||||
|
indexName := "testindexwithfieldsinstruct"
|
||||||
|
docType := "tweet"
|
||||||
|
docId := "1234"
|
||||||
|
|
||||||
|
conn := NewConnection(ES_HOST, ES_PORT)
|
||||||
|
// just in case
|
||||||
|
conn.DeleteIndex(indexName)
|
||||||
|
|
||||||
|
_, err := conn.CreateIndex(indexName, map[string]interface{}{})
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
defer conn.DeleteIndex(indexName)
|
||||||
|
|
||||||
|
d := Document{
|
||||||
|
Index: indexName,
|
||||||
|
Type: docType,
|
||||||
|
Id: docId,
|
||||||
|
Fields: struct {
|
||||||
|
user string
|
||||||
|
message string
|
||||||
|
}{
|
||||||
|
"foo",
|
||||||
|
"bar",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
extraArgs := make(url.Values, 1)
|
||||||
|
extraArgs.Set("ttl", "86400000")
|
||||||
|
response, err := conn.Index(d, extraArgs)
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
|
||||||
|
expectedResponse := Response{
|
||||||
|
Index: indexName,
|
||||||
|
Id: docId,
|
||||||
|
Type: docType,
|
||||||
|
Version: 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.Assert(response, DeepEquals, expectedResponse)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GoesTestSuite) TestIndexWithFieldsNotInMapOrStruct(c *C) {
|
||||||
|
indexName := "testindexwithfieldsnotinmaporstruct"
|
||||||
|
docType := "tweet"
|
||||||
|
docId := "1234"
|
||||||
|
|
||||||
|
conn := NewConnection(ES_HOST, ES_PORT)
|
||||||
|
// just in case
|
||||||
|
conn.DeleteIndex(indexName)
|
||||||
|
|
||||||
|
_, err := conn.CreateIndex(indexName, map[string]interface{}{})
|
||||||
|
c.Assert(err, IsNil)
|
||||||
|
defer conn.DeleteIndex(indexName)
|
||||||
|
|
||||||
|
d := Document{
|
||||||
|
Index: indexName,
|
||||||
|
Type: docType,
|
||||||
|
Id: docId,
|
||||||
|
Fields: "test",
|
||||||
|
}
|
||||||
|
|
||||||
|
extraArgs := make(url.Values, 1)
|
||||||
|
extraArgs.Set("ttl", "86400000")
|
||||||
|
_, err = conn.Index(d, extraArgs)
|
||||||
|
c.Assert(err, Not(IsNil))
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GoesTestSuite) TestIndexIdDefined(c *C) {
|
func (s *GoesTestSuite) TestIndexIdDefined(c *C) {
|
||||||
indexName := "testindexiddefined"
|
indexName := "testindexiddefined"
|
||||||
docType := "tweet"
|
docType := "tweet"
|
||||||
@ -534,7 +601,7 @@ func (s *GoesTestSuite) TestSearch(c *C) {
|
|||||||
"query": map[string]interface{}{
|
"query": map[string]interface{}{
|
||||||
"bool": map[string]interface{}{
|
"bool": map[string]interface{}{
|
||||||
"must": []map[string]interface{}{
|
"must": []map[string]interface{}{
|
||||||
map[string]interface{}{
|
{
|
||||||
"match_all": map[string]interface{}{},
|
"match_all": map[string]interface{}{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -547,7 +614,7 @@ func (s *GoesTestSuite) TestSearch(c *C) {
|
|||||||
Total: 1,
|
Total: 1,
|
||||||
MaxScore: 1.0,
|
MaxScore: 1.0,
|
||||||
Hits: []Hit{
|
Hits: []Hit{
|
||||||
Hit{
|
{
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
Id: docId,
|
Id: docId,
|
||||||
@ -592,7 +659,7 @@ func (s *GoesTestSuite) TestIndexStatus(c *C) {
|
|||||||
c.Assert(sizeInBytes > 0, Equals, true)
|
c.Assert(sizeInBytes > 0, Equals, true)
|
||||||
|
|
||||||
expectedIndices := map[string]IndexStatus{
|
expectedIndices := map[string]IndexStatus{
|
||||||
indexName: IndexStatus{
|
indexName: {
|
||||||
Index: map[string]interface{}{
|
Index: map[string]interface{}{
|
||||||
"primary_size_in_bytes": primarySizeInBytes,
|
"primary_size_in_bytes": primarySizeInBytes,
|
||||||
"size_in_bytes": sizeInBytes,
|
"size_in_bytes": sizeInBytes,
|
||||||
@ -633,7 +700,7 @@ func (s *GoesTestSuite) TestScroll(c *C) {
|
|||||||
docType := "tweet"
|
docType := "tweet"
|
||||||
|
|
||||||
tweets := []Document{
|
tweets := []Document{
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -644,7 +711,7 @@ func (s *GoesTestSuite) TestScroll(c *C) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -655,7 +722,7 @@ func (s *GoesTestSuite) TestScroll(c *C) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -733,7 +800,7 @@ func (s *GoesTestSuite) TestAggregations(c *C) {
|
|||||||
docType := "tweet"
|
docType := "tweet"
|
||||||
|
|
||||||
tweets := []Document{
|
tweets := []Document{
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -745,7 +812,7 @@ func (s *GoesTestSuite) TestAggregations(c *C) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
@ -757,7 +824,7 @@ func (s *GoesTestSuite) TestAggregations(c *C) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Document{
|
{
|
||||||
Id: nil,
|
Id: nil,
|
||||||
Index: indexName,
|
Index: indexName,
|
||||||
Type: docType,
|
Type: docType,
|
||||||
|
@ -102,7 +102,7 @@ type Document struct {
|
|||||||
Type string
|
Type string
|
||||||
Id interface{}
|
Id interface{}
|
||||||
BulkCommand string
|
BulkCommand string
|
||||||
Fields map[string]interface{}
|
Fields interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Represents the "items" field in a _bulk response
|
// Represents the "items" field in a _bulk response
|
||||||
|
Loading…
Reference in New Issue
Block a user