2019-04-22 02:59:20 +00:00

388 lines
9.6 KiB
Go

// Copyright 2012-present Oliver Eilhard. All rights reserved.
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.
package elastic
import (
"context"
"encoding/json"
"io"
_ "net/http"
"testing"
)
func TestScroll(t *testing.T) {
client := setupTestClientAndCreateIndex(t)
tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
// Add all documents
_, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("3").BodyJson(&tweet3).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Flush().Index(testIndexName).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
// Should return all documents. Just don't call Do yet!
svc := client.Scroll(testIndexName).Size(1)
pages := 0
docs := 0
for {
res, err := svc.Do(context.TODO())
if err == io.EOF {
break
}
if err != nil {
t.Fatal(err)
}
if res == nil {
t.Fatal("expected results != nil; got nil")
}
if res.Hits == nil {
t.Fatal("expected results.Hits != nil; got nil")
}
if want, have := int64(3), res.Hits.TotalHits; want != have {
t.Fatalf("expected results.Hits.TotalHits = %d; got %d", want, have)
}
if want, have := 1, len(res.Hits.Hits); want != have {
t.Fatalf("expected len(results.Hits.Hits) = %d; got %d", want, have)
}
pages++
for _, hit := range res.Hits.Hits {
if hit.Index != testIndexName {
t.Fatalf("expected SearchResult.Hits.Hit.Index = %q; got %q", testIndexName, hit.Index)
}
item := make(map[string]interface{})
err := json.Unmarshal(*hit.Source, &item)
if err != nil {
t.Fatal(err)
}
docs++
}
if len(res.ScrollId) == 0 {
t.Fatalf("expected scrollId in results; got %q", res.ScrollId)
}
}
if want, have := 3, pages; want != have {
t.Fatalf("expected to retrieve %d pages; got %d", want, have)
}
if want, have := 3, docs; want != have {
t.Fatalf("expected to retrieve %d hits; got %d", want, have)
}
err = svc.Clear(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = svc.Do(context.TODO())
if err == nil {
t.Fatal("expected to fail")
}
}
func TestScrollWithQueryAndSort(t *testing.T) {
client := setupTestClientAndCreateIndex(t)
// client := setupTestClientAndCreateIndexAndAddDocs(t, SetTraceLog(log.New(os.Stdout, "", log.LstdFlags)))
tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch."}
tweet2 := tweet{User: "olivere", Message: "Another unrelated topic."}
tweet3 := tweet{User: "sandrae", Message: "Cycling is fun."}
// Add all documents
_, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("3").BodyJson(&tweet3).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Flush().Index(testIndexName).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
// Create a scroll service that returns tweets from user olivere
// and returns them sorted by "message", in reverse order.
//
// Just don't call Do yet!
svc := client.Scroll(testIndexName).
Query(NewTermQuery("user", "olivere")).
Sort("message", false).
Size(1)
docs := 0
pages := 0
for {
res, err := svc.Do(context.TODO())
if err == io.EOF {
break
}
if err != nil {
t.Fatal(err)
}
if err != nil {
t.Fatal(err)
}
if res == nil {
t.Fatal("expected results != nil; got nil")
}
if res.Hits == nil {
t.Fatal("expected results.Hits != nil; got nil")
}
if want, have := int64(2), res.Hits.TotalHits; want != have {
t.Fatalf("expected results.Hits.TotalHits = %d; got %d", want, have)
}
if want, have := 1, len(res.Hits.Hits); want != have {
t.Fatalf("expected len(results.Hits.Hits) = %d; got %d", want, have)
}
pages++
for _, hit := range res.Hits.Hits {
if hit.Index != testIndexName {
t.Fatalf("expected SearchResult.Hits.Hit.Index = %q; got %q", testIndexName, hit.Index)
}
item := make(map[string]interface{})
err := json.Unmarshal(*hit.Source, &item)
if err != nil {
t.Fatal(err)
}
docs++
}
}
if want, have := 2, pages; want != have {
t.Fatalf("expected to retrieve %d pages; got %d", want, have)
}
if want, have := 2, docs; want != have {
t.Fatalf("expected to retrieve %d hits; got %d", want, have)
}
}
func TestScrollWithBody(t *testing.T) {
// client := setupTestClientAndCreateIndexAndLog(t)
client := setupTestClientAndCreateIndex(t)
tweet1 := tweet{User: "olivere", Message: "Welcome to Golang and Elasticsearch.", Retweets: 4}
tweet2 := tweet{User: "olivere", Message: "Another unrelated topic.", Retweets: 10}
tweet3 := tweet{User: "sandrae", Message: "Cycling is fun.", Retweets: 3}
// Add all documents
_, err := client.Index().Index(testIndexName).Type("tweet").Id("1").BodyJson(&tweet1).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("2").BodyJson(&tweet2).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Index().Index(testIndexName).Type("tweet").Id("3").BodyJson(&tweet3).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
_, err = client.Flush().Index(testIndexName).Do(context.TODO())
if err != nil {
t.Fatal(err)
}
// Test with simple strings and a map
var tests = []struct {
Body interface{}
ExpectedTotalHits int64
ExpectedDocs int
ExpectedPages int
}{
{
Body: `{"query":{"match_all":{}}}`,
ExpectedTotalHits: 3,
ExpectedDocs: 3,
ExpectedPages: 3,
},
{
Body: `{"query":{"term":{"user":"olivere"}},"sort":["_doc"]}`,
ExpectedTotalHits: 2,
ExpectedDocs: 2,
ExpectedPages: 2,
},
{
Body: `{"query":{"term":{"user":"olivere"}},"sort":[{"retweets":"desc"}]}`,
ExpectedTotalHits: 2,
ExpectedDocs: 2,
ExpectedPages: 2,
},
{
Body: map[string]interface{}{
"query": map[string]interface{}{
"term": map[string]interface{}{
"user": "olivere",
},
},
"sort": []interface{}{"_doc"},
},
ExpectedTotalHits: 2,
ExpectedDocs: 2,
ExpectedPages: 2,
},
}
for i, tt := range tests {
// Should return all documents. Just don't call Do yet!
svc := client.Scroll(testIndexName).Size(1).Body(tt.Body)
pages := 0
docs := 0
for {
res, err := svc.Do(context.TODO())
if err == io.EOF {
break
}
if err != nil {
t.Fatal(err)
}
if res == nil {
t.Fatalf("#%d: expected results != nil; got nil", i)
}
if res.Hits == nil {
t.Fatalf("#%d: expected results.Hits != nil; got nil", i)
}
if want, have := tt.ExpectedTotalHits, res.Hits.TotalHits; want != have {
t.Fatalf("#%d: expected results.Hits.TotalHits = %d; got %d", i, want, have)
}
if want, have := 1, len(res.Hits.Hits); want != have {
t.Fatalf("#%d: expected len(results.Hits.Hits) = %d; got %d", i, want, have)
}
pages++
for _, hit := range res.Hits.Hits {
if hit.Index != testIndexName {
t.Fatalf("#%d: expected SearchResult.Hits.Hit.Index = %q; got %q", i, testIndexName, hit.Index)
}
item := make(map[string]interface{})
err := json.Unmarshal(*hit.Source, &item)
if err != nil {
t.Fatalf("#%d: %v", i, err)
}
docs++
}
if len(res.ScrollId) == 0 {
t.Fatalf("#%d: expected scrollId in results; got %q", i, res.ScrollId)
}
}
if want, have := tt.ExpectedPages, pages; want != have {
t.Fatalf("#%d: expected to retrieve %d pages; got %d", i, want, have)
}
if want, have := tt.ExpectedDocs, docs; want != have {
t.Fatalf("#%d: expected to retrieve %d hits; got %d", i, want, have)
}
err = svc.Clear(context.TODO())
if err != nil {
t.Fatalf("#%d: failed to clear scroll context: %v", i, err)
}
_, err = svc.Do(context.TODO())
if err == nil {
t.Fatalf("#%d: expected to fail", i)
}
}
}
func TestScrollWithSlice(t *testing.T) {
client := setupTestClientAndCreateIndexAndAddDocs(t) //, SetTraceLog(log.New(os.Stdout, "", 0)))
// Should return all documents. Just don't call Do yet!
sliceQuery := NewSliceQuery().Id(0).Max(2)
svc := client.Scroll(testIndexName).Slice(sliceQuery).Size(1)
pages := 0
docs := 0
for {
res, err := svc.Do(context.TODO())
if err == io.EOF {
break
}
if err != nil {
t.Fatal(err)
}
if res == nil {
t.Fatal("expected results != nil; got nil")
}
if res.Hits == nil {
t.Fatal("expected results.Hits != nil; got nil")
}
pages++
for _, hit := range res.Hits.Hits {
if hit.Index != testIndexName {
t.Fatalf("expected SearchResult.Hits.Hit.Index = %q; got %q", testIndexName, hit.Index)
}
item := make(map[string]interface{})
err := json.Unmarshal(*hit.Source, &item)
if err != nil {
t.Fatal(err)
}
docs++
}
if len(res.ScrollId) == 0 {
t.Fatalf("expected scrollId in results; got %q", res.ScrollId)
}
}
if pages == 0 {
t.Fatal("expected to retrieve some pages")
}
if docs == 0 {
t.Fatal("expected to retrieve some hits")
}
if err := svc.Clear(context.TODO()); err != nil {
t.Fatal(err)
}
if _, err := svc.Do(context.TODO()); err == nil {
t.Fatal("expected to fail")
}
}