Files
es-demo/operations/index/search_test.go

344 lines
6.8 KiB
Go

package index
import (
"context"
"testing"
"time"
)
// TestSearchIntegration tests search operations.
func TestSearchIntegration(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
c := setupIntegrationTest(t)
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
indexName := "test-search-integration"
// Setup index with mapping
config := &IndexConfig{
Mappings: map[string]any{
"properties": map[string]any{
"title": map[string]any{
"type": "text",
},
"category": map[string]any{
"type": "keyword",
},
"price": map[string]any{
"type": "integer",
},
},
},
}
err := CreateIndex(ctx, c, indexName, config)
if err != nil {
t.Fatalf("setup: CreateIndex() error = %v", err)
}
defer func() {
_ = DeleteIndex(ctx, c, indexName)
}()
// Index test documents
docs := []*Document{
{
ID: "1",
Source: map[string]any{
"title": "Go Programming Language",
"category": "books",
"price": 50,
},
},
{
ID: "2",
Source: map[string]any{
"title": "Python for Beginners",
"category": "books",
"price": 40,
},
},
{
ID: "3",
Source: map[string]any{
"title": "JavaScript Guide",
"category": "books",
"price": 45,
},
},
}
err = BulkIndexDocuments(ctx, c, indexName, docs)
if err != nil {
t.Fatalf("setup: BulkIndexDocuments() error = %v", err)
}
// Give ES a moment to index
time.Sleep(1 * time.Second)
// Test 1: Match query
t.Run("MatchQuery", func(t *testing.T) {
query := &SearchQuery{
Query: MatchQuery("title", "Programming"),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value == 0 {
t.Error("Search() returned no results")
}
t.Logf("Match query found %d results", result.Hits.Total.Value)
})
// Test 2: Term query
t.Run("TermQuery", func(t *testing.T) {
query := &SearchQuery{
Query: TermQuery("category", "books"),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value != 3 {
t.Errorf("Term query found %d results, want 3", result.Hits.Total.Value)
}
t.Logf("Term query found %d results", result.Hits.Total.Value)
})
// Test 3: Range query
t.Run("RangeQuery", func(t *testing.T) {
query := &SearchQuery{
Query: RangeQuery("price", 40, 50),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value == 0 {
t.Error("Range query returned no results")
}
t.Logf("Range query found %d results", result.Hits.Total.Value)
})
// Test 4: Bool query
t.Run("BoolQuery", func(t *testing.T) {
boolQ := &BoolQuery{
Must: []map[string]any{
TermQuery("category", "books"),
},
Filter: []map[string]any{
RangeQuery("price", nil, 45),
},
}
query := &SearchQuery{
Query: boolQ.ToBoolQuery(),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value == 0 {
t.Error("Bool query returned no results")
}
t.Logf("Bool query found %d results", result.Hits.Total.Value)
})
// Test 5: Match all query
t.Run("MatchAllQuery", func(t *testing.T) {
query := &SearchQuery{
Query: MatchAllQuery(),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value != 3 {
t.Errorf("Match all query found %d results, want 3", result.Hits.Total.Value)
}
t.Logf("Match all query found %d results", result.Hits.Total.Value)
})
// Test 6: Pagination
t.Run("Pagination", func(t *testing.T) {
query := &SearchQuery{
Query: MatchAllQuery(),
Size: 1,
From: 1,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if len(result.Hits.Hits) != 1 {
t.Errorf("Pagination returned %d hits, want 1", len(result.Hits.Hits))
}
t.Log("Pagination test passed")
})
// Test 7: Multi-match query
t.Run("MultiMatchQuery", func(t *testing.T) {
query := &SearchQuery{
Query: MultiMatchQuery("Programming", "title", "category"),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result.Hits.Total.Value == 0 {
t.Error("Multi-match query returned no results")
}
t.Logf("Multi-match query found %d results", result.Hits.Total.Value)
})
}
func TestSearch(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
c := setupIntegrationTest(t)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
indexName := "test-search"
// Cleanup any existing index first
_ = DeleteIndex(ctx, c, indexName)
// Setup
err := CreateIndex(ctx, c, indexName, nil)
if err != nil {
t.Fatalf("setup: CreateIndex() error = %v", err)
}
defer func() {
_ = DeleteIndex(ctx, c, indexName)
}()
// Index a document
doc := &Document{
Source: map[string]any{
"message": "test search",
},
}
_, err = IndexDocument(ctx, c, indexName, doc)
if err != nil {
t.Fatalf("setup: IndexDocument() error = %v", err)
}
// Give ES a moment
time.Sleep(1 * time.Second)
query := &SearchQuery{
Query: MatchAllQuery(),
Size: 10,
}
result, err := Search(ctx, c, indexName, query)
if err != nil {
t.Fatalf("Search() error = %v", err)
}
if result == nil {
t.Error("Search() returned nil")
}
t.Logf("Search succeeded: found %d results", result.Hits.Total.Value)
}
func TestMatchQuery(t *testing.T) {
query := MatchQuery("field", "value")
if query == nil {
t.Error("MatchQuery() returned nil")
}
if _, ok := query["match"]; !ok {
t.Error("MatchQuery() missing 'match' key")
}
t.Log("MatchQuery test passed")
}
func TestTermQuery(t *testing.T) {
query := TermQuery("field", "value")
if query == nil {
t.Error("TermQuery() returned nil")
}
if _, ok := query["term"]; !ok {
t.Error("TermQuery() missing 'term' key")
}
t.Log("TermQuery test passed")
}
func TestRangeQuery(t *testing.T) {
query := RangeQuery("age", 18, 65)
if query == nil {
t.Error("RangeQuery() returned nil")
}
if _, ok := query["range"]; !ok {
t.Error("RangeQuery() missing 'range' key")
}
t.Log("RangeQuery test passed")
}
func TestBoolQuery(t *testing.T) {
boolQ := &BoolQuery{
Must: []map[string]any{
MatchQuery("field", "value"),
},
}
query := boolQ.ToBoolQuery()
if query == nil {
t.Error("ToBoolQuery() returned nil")
}
if _, ok := query["bool"]; !ok {
t.Error("ToBoolQuery() missing 'bool' key")
}
t.Log("BoolQuery test passed")
}