github.com/opensearch-project/opensearch-go/v2@v2.3.0/opensearchutil/bulk_indexer_example_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  //
     3  // The OpenSearch Contributors require contributions made to
     4  // this file be licensed under the Apache-2.0 license or a
     5  // compatible open source license.
     6  //
     7  // Modifications Copyright OpenSearch Contributors. See
     8  // GitHub history for details.
     9  
    10  // Licensed to Elasticsearch B.V. under one or more contributor
    11  // license agreements. See the NOTICE file distributed with
    12  // this work for additional information regarding copyright
    13  // ownership. Elasticsearch B.V. licenses this file to you under
    14  // the Apache License, Version 2.0 (the "License"); you may
    15  // not use this file except in compliance with the License.
    16  // You may obtain a copy of the License at
    17  //
    18  //    http://www.apache.org/licenses/LICENSE-2.0
    19  //
    20  // Unless required by applicable law or agreed to in writing,
    21  // software distributed under the License is distributed on an
    22  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    23  // KIND, either express or implied.  See the License for the
    24  // specific language governing permissions and limitations
    25  // under the License.
    26  
    27  // +build !integration
    28  
    29  package opensearchutil_test
    30  
    31  import (
    32  	"context"
    33  	"fmt"
    34  	"log"
    35  	"strings"
    36  	"time"
    37  
    38  	"github.com/opensearch-project/opensearch-go/v2"
    39  	"github.com/opensearch-project/opensearch-go/v2/opensearchutil"
    40  )
    41  
    42  func ExampleNewBulkIndexer() {
    43  	log.SetFlags(0)
    44  
    45  	// Create the OpenSearch client
    46  	//
    47  	client, err := opensearch.NewClient(opensearch.Config{
    48  		// Retry on 429 TooManyRequests statuses
    49  		//
    50  		RetryOnStatus: []int{502, 503, 504, 429},
    51  
    52  		// A simple incremental backoff function
    53  		//
    54  		RetryBackoff: func(i int) time.Duration { return time.Duration(i) * 100 * time.Millisecond },
    55  
    56  		// Retry up to 5 attempts
    57  		//
    58  		MaxRetries: 5,
    59  	})
    60  	if err != nil {
    61  		log.Fatalf("Error creating the client: %s", err)
    62  	}
    63  
    64  	// Create the indexer
    65  	//
    66  	indexer, err := opensearchutil.NewBulkIndexer(opensearchutil.BulkIndexerConfig{
    67  		Client:     client, // The OpenSearch client
    68  		Index:      "test", // The default index name
    69  		NumWorkers: 4,      // The number of worker goroutines (default: number of CPUs)
    70  		FlushBytes: 5e+6,   // The flush threshold in bytes (default: 5M)
    71  	})
    72  	if err != nil {
    73  		log.Fatalf("Error creating the indexer: %s", err)
    74  	}
    75  
    76  	// Add an item to the indexer
    77  	//
    78  	err = indexer.Add(
    79  		context.Background(),
    80  		opensearchutil.BulkIndexerItem{
    81  			// Action field configures the operation to perform (index, create, delete, update)
    82  			Action: "index",
    83  
    84  			// DocumentID is the optional document ID
    85  			DocumentID: "1",
    86  
    87  			// Body is an `io.Reader` with the payload
    88  			Body: strings.NewReader(`{"title":"Test"}`),
    89  
    90  			// OnSuccess is the optional callback for each successful operation
    91  			OnSuccess: func(
    92  				ctx context.Context,
    93  				item opensearchutil.BulkIndexerItem,
    94  				res opensearchutil.BulkIndexerResponseItem,
    95  			) {
    96  				fmt.Printf("[%d] %s test/%s", res.Status, res.Result, item.DocumentID)
    97  			},
    98  
    99  			// OnFailure is the optional callback for each failed operation
   100  			OnFailure: func(
   101  				ctx context.Context,
   102  				item opensearchutil.BulkIndexerItem,
   103  				res opensearchutil.BulkIndexerResponseItem, err error,
   104  			) {
   105  				if err != nil {
   106  					log.Printf("ERROR: %s", err)
   107  				} else {
   108  					log.Printf("ERROR: %s: %s", res.Error.Type, res.Error.Reason)
   109  				}
   110  			},
   111  		},
   112  	)
   113  	if err != nil {
   114  		log.Fatalf("Unexpected error: %s", err)
   115  	}
   116  
   117  	// Close the indexer channel and flush remaining items
   118  	//
   119  	if err := indexer.Close(context.Background()); err != nil {
   120  		log.Fatalf("Unexpected error: %s", err)
   121  	}
   122  
   123  	// Report the indexer statistics
   124  	//
   125  	stats := indexer.Stats()
   126  	if stats.NumFailed > 0 {
   127  		log.Fatalf("Indexed [%d] documents with [%d] errors", stats.NumFlushed, stats.NumFailed)
   128  	} else {
   129  		log.Printf("Successfully indexed [%d] documents", stats.NumFlushed)
   130  	}
   131  
   132  	// For optimal performance, consider using a third-party package for JSON decoding and HTTP transport.
   133  }