본문 바로가기
WIKI 기술 지식 베이스

Go client

원문 보기 위키 갱신

출처: 문서

본문

Go 클라이언트

OpenSearch Go 클라이언트를 사용하면 Go 애플리케이션을 OpenSearch 클러스터의 데이터와 연결할 수 있어요. 이 시작하기 가이드에서는 OpenSearch에 연결하고, 문서를 인덱싱하고, 쿼리를 실행하는 방법을 보여줘요. 클라이언트의 전체 API 문서와 추가 예제는 Go 클라이언트 API 문서를 참고하세요.

클라이언트 소스 코드는 opensearch-go 저장소에서 확인할 수 있어요.

Go 클라이언트 설치하기

Go 클라이언트를 사용하려면 Go 1.26 이상이 필요해요.

새 프로젝트를 시작하는 경우라면, 다음 명령어를 실행해 새 모듈을 만드세요:

go mod init <mymodulename>

{% include copy.html %}

프로젝트에 Go 클라이언트를 추가하려면 다음 명령어를 실행하세요:

go get github.com/opensearch-project/opensearch-go/v5

{% include copy.html %}

클라이언트 버전 5는 버전 4용으로 작성된 코드와 호환되지 않아요. 마이그레이션 방법은 v5 업그레이드 가이드를 참고하세요.

OpenSearch에 연결하기

이 페이지의 예제에서는 다음 임포트를 사용해요:

import (
	"context"
	"encoding/json"
	"fmt"
	"strings"

	"github.com/opensearch-project/opensearch-go/v5"
	"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
	"github.com/opensearch-project/opensearch-go/v5/opensearchutil"
)

{% include copy.html %}

기본 OpenSearch 호스트에 연결하려면, Security 플러그인을 사용하는 경우 https://localhost:9200 주소로 클라이언트 객체를 만드세요:

client, err := opensearchapi.NewClient(opensearchapi.Config{
	Client: opensearch.Config{
		Addresses:            []string{"https://localhost:9200"},
		InsecureSkipVerify:   true,    // For testing only. Use certificate for validation.
		Username:             "admin", // For testing only. Don't store credentials in code.
		Password:             "<custom-admin-password>",
		DiscoverNodesOnStart: new(false),
	},
})

{% include copy.html %}

Security 플러그인을 사용하지 않는다면 http://localhost:9200 주소로 클라이언트 객체를 만드세요:

client, err := opensearchapi.NewClient(opensearchapi.Config{
	Client: opensearch.Config{
		Addresses:            []string{"http://localhost:9200"},
		DiscoverNodesOnStart: new(false),
	},
})

{% include copy.html %}

기본적으로 클라이언트는 시작할 때 클러스터의 노드를 탐색한 뒤 노드의 publish 주소로 요청을 보내요. 이 주소에 애플리케이션에서 접근할 수 없으면---예를 들어 OpenSearch가 Docker에서 실행될 때---요청이 시간 초과돼요. DiscoverNodesOnStart를 false로 설정하면 클라이언트가 Addresses에 지정한 주소로만 요청을 보내요.

Amazon OpenSearch Service에 연결하기

다음 예제에서 엔드포인트는 여러분의 도메인 엔드포인트로 바꾸세요. 도메인 엔드포인트는 Amazon OpenSearch Service 콘솔의 도메인 세부 정보 페이지에 나열되어 있어요.

다음 예제는 Amazon OpenSearch Service에 연결하는 방법을 보여줘요:

package main

import (
	"context"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/opensearch-project/opensearch-go/v5"
	"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
	requestsigner "github.com/opensearch-project/opensearch-go/v5/signer/awsv2"
)

const endpoint = "https://search-<domain-name>-<id>.us-east-1.es.amazonaws.com" // OpenSearch domain endpoint

func main() {
	ctx := context.Background()

	awsCfg, err := config.LoadDefaultConfig(ctx,
		config.WithRegion("us-east-1"),
		config.WithCredentialsProvider(
			getCredentialProvider("<AWS_ACCESS_KEY>", "<AWS_SECRET_ACCESS_KEY>", "<AWS_SESSION_TOKEN>"),
		),
	)
	if err != nil {
		log.Fatal(err) // Do not log.Fatal in a production-ready app.
	}

	// Create an AWS request signer for Amazon OpenSearch Service.
	signer, err := requestsigner.NewSignerWithService(awsCfg, "es")
	if err != nil {
		log.Fatal(err) // Do not log.Fatal in a production-ready app.
	}

	// Create an OpenSearch client that uses the request signer.
	client, err := opensearchapi.NewClient(opensearchapi.Config{
		Client: opensearch.Config{
			Addresses:            []string{endpoint},
			Signer:               signer,
			DiscoverNodesOnStart: new(false),
		},
	})
	if err != nil {
		log.Fatal("client creation err", err)
	}

	_ = client
	// Your code here
}

func getCredentialProvider(accessKey, secretAccessKey, token string) aws.CredentialsProviderFunc {
	return func(ctx context.Context) (aws.Credentials, error) {
		c := &aws.Credentials{
			AccessKeyID:     accessKey,
			SecretAccessKey: secretAccessKey,
			SessionToken:    token,
		}
		return *c, nil
	}
}

{% include copy.html %}

이 예제나 Amazon OpenSearch Serverless 예제에서 기본 AWS 자격 증명 체인을 사용하려면 config.WithCredentialsProvider 옵션을 생략하세요.

Amazon OpenSearch Serverless에 연결하기

다음 예제에서 엔드포인트는 여러분의 컬렉션 엔드포인트로 바꾸세요. 컬렉션 엔드포인트는 Amazon OpenSearch Service 콘솔의 컬렉션 세부 정보 페이지에 나열되어 있어요.

다음 예제는 Amazon OpenSearch Serverless에 연결하는 방법을 보여줘요:

package main

import (
	"context"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/opensearch-project/opensearch-go/v5"
	"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
	requestsigner "github.com/opensearch-project/opensearch-go/v5/signer/awsv2"
)

const endpoint = "https://<collection-id>.us-east-1.aoss.amazonaws.com" // OpenSearch Serverless collection endpoint

func main() {
	ctx := context.Background()

	awsCfg, err := config.LoadDefaultConfig(ctx,
		config.WithRegion("us-east-1"),
		config.WithCredentialsProvider(
			getCredentialProvider("<AWS_ACCESS_KEY>", "<AWS_SECRET_ACCESS_KEY>", "<AWS_SESSION_TOKEN>"),
		),
	)
	if err != nil {
		log.Fatal(err) // Do not log.Fatal in a production-ready app.
	}

	// Create an AWS request signer for Amazon OpenSearch Serverless.
	signer, err := requestsigner.NewSignerWithService(awsCfg, "aoss")
	if err != nil {
		log.Fatal(err) // Do not log.Fatal in a production-ready app.
	}

	// Create an OpenSearch client that uses the request signer.
	client, err := opensearchapi.NewClient(opensearchapi.Config{
		Client: opensearch.Config{
			Addresses:            []string{endpoint},
			Signer:               signer,
			DiscoverNodesOnStart: new(false),
		},
	})
	if err != nil {
		log.Fatal("client creation err", err)
	}

	_ = client
	// Your code here
}

func getCredentialProvider(accessKey, secretAccessKey, token string) aws.CredentialsProviderFunc {
	return func(ctx context.Context) (aws.Credentials, error) {
		c := &aws.Credentials{
			AccessKeyID:     accessKey,
			SecretAccessKey: secretAccessKey,
			SessionToken:    token,
		}
		return *c, nil
	}
}

{% include copy.html %}

Amazon OpenSearch Serverless는 OpenSearch API 작업 중 일부만 지원하며, 이 페이지의 예제에서 사용하는 refresh 파라미터는 지원하지 않아요. 자세한 내용은 Amazon OpenSearch Serverless에서 지원하는 작업 및 플러그인을 참고하세요. {: .note}

opensearchapi.NewClient 생성자는 opensearchapi.Config{} 타입을 받아요. 이 타입의 Client 필드에는 opensearch.Config{} 타입이 들어 있는데, OpenSearch 노드 주소 목록이나 사용자 이름과 비밀번호 조합 같은 옵션으로 커스터마이즈할 수 있어요.

여러 OpenSearch 노드에 연결하려면 Addresses 파라미터에 노드들을 지정하세요:

var (
	urls = []string{"http://localhost:9200", "http://localhost:9201", "http://localhost:9202"}
)

client, err := opensearchapi.NewClient(opensearchapi.Config{
	Client: opensearch.Config{
		Addresses:            urls,
		DiscoverNodesOnStart: new(false),
	},
})

{% include copy.html %}

Go 클라이언트는 기본적으로 요청을 최대 세 번까지 재시도해요. 재시도 횟수를 바꾸려면 MaxRetries 파라미터를 설정하세요. 또한 RetryOnStatus 파라미터를 설정하면 요청을 재시도할 응답 코드 목록을 바꿀 수 있어요. 다음 코드 조각은 커스텀 MaxRetries와 RetryOnStatus 값으로 새 Go 클라이언트를 만들어요:

client, err := opensearchapi.NewClient(opensearchapi.Config{
	Client: opensearch.Config{
		Addresses:            []string{"http://localhost:9200"},
		DiscoverNodesOnStart: new(false),
		MaxRetries:           5,
		RetryOnStatus:        []int{502, 503, 504},
	},
})

{% include copy.html %}

샘플 데이터

이 페이지의 예제에서는 문서를 표현하기 위해 Student 구조체를 사용해요. JSON 태그가 인덱싱된 문서의 필드 이름을 결정해요:

type Student struct {
	FirstName string  `json:"firstName"`
	LastName  string  `json:"lastName"`
	GPA       float64 `json:"gpa"`
	GradDate  string  `json:"gradDate"`
}

{% include copy.html %}

인덱스 생성하기

다음 예제는 프라이머리 샤드 하나와 레플리카 하나가 있는 인덱스를 만들어요. 이 예제에서는 gradDate 필드를 yyyy-MM-dd 형식의 date로 명시적으로 매핑해요. 나머지 문서 필드는 문서를 인덱싱할 때 OpenSearch가 동적으로 매핑해요:

ctx := context.Background()
index := "students"
body := `{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 1
    }
  },
  "mappings": {
    "properties": {
      "gradDate": { "type": "date", "format": "yyyy-MM-dd" }
    }
  }
}`
createResp, err := client.Indices.Create(ctx, opensearchapi.IndicesCreateReq{
	Index:      index,
	BodyReader: strings.NewReader(body),
})

{% include copy.html %}

문서 인덱싱하기

다음 코드를 사용해 문서를 인덱싱해 보세요. Refresh 파라미터를 true로 설정하면 문서를 즉시 검색할 수 있게 돼요:

student := Student{FirstName: "John", LastName: "Doe", GPA: 3.89, GradDate: "2022-05-15"}
indexResp, err := client.Doc.Index(ctx, opensearchapi.IndexReq{
	Index:  index,
	ID:     "1",
	Body:   opensearchutil.NewJSONReader(student),
	Params: &opensearchapi.IndexParams{Refresh: "true"},
})

{% include copy.html %}

벌크 인덱싱

다음 코드를 사용하면 하나의 요청으로 여러 문서를 인덱싱할 수 있어요. 요청 본문에는 각 문서마다 액션 라인 다음에 문서 라인이 포함되고, 각 줄은 반드시 개행 문자로 끝나야 해요:

students := []struct {
	id      string
	student Student
}{
	{"2", Student{FirstName: "Paulo", LastName: "Santos", GPA: 3.93, GradDate: "2021-05-20"}},
	{"3", Student{FirstName: "Shirley", LastName: "Rodriguez", GPA: 3.91, GradDate: "2019-05-10"}},
}
var bulkBody strings.Builder
for _, s := range students {
	doc, err := json.Marshal(s.student)
	if err != nil {
		return err
	}
	fmt.Fprintf(&bulkBody, "{\"index\":{\"_id\":%q}}\n%s\n", s.id, doc)
}
bulkResp, err := client.Doc.Bulk(ctx, opensearchapi.BulkReq{
	Index:  index,
	Body:   strings.NewReader(bulkBody.String()),
	Params: &opensearchapi.BulkParams{Refresh: "true"},
})

{% include copy.html %}

작업 중 하나라도 실패하면 메서드가 응답과 함께 *opensearchapi.PartialBulkError 에러를 반환해요. 각 작업의 결과를 확인하려면 bulkResp.Items 필드를 살펴보세요.

문서 검색하기

다음 코드를 사용하면 인덱스의 모든 문서를 검색할 수 있어요:

searchResp, err := client.Search(ctx, &opensearchapi.SearchReq{
	Indices: []string{index},
})
if err != nil {
	return err
}
for _, hit := range searchResp.Hits.Hits {
	var s Student
	if err := json.Unmarshal(hit.Source, &s); err != nil {
		return err
	}
	out, err := json.Marshal(s)
	if err != nil {
		return err
	}
	fmt.Println(string(out))
}

{% include copy.html %}

searchResp.Hits.Hits의 각 항목에서 ID 필드는 문서 ID에 대한 포인터를 담고 있고, Source 필드는 raw JSON 형태의 문서를 담고 있어요. 문서 필드에 접근하려면 Source를 Student 구조체로 언마샬하세요:

for _, hit := range searchResp.Hits.Hits {
	var s Student
	if err := json.Unmarshal(hit.Source, &s); err != nil {
		return err
	}
	fmt.Printf("ID: %s, name: %s %s, GPA: %v, graduation date: %s\n", *hit.ID, s.FirstName, s.LastName, s.GPA, s.GradDate)
}

{% include copy.html %}

range 쿼리를 사용해 검색할 수도 있어요:

searchResp, err := client.Search(ctx, &opensearchapi.SearchReq{
	Indices:    []string{index},
	BodyReader: strings.NewReader(`{"query": {"range": {"gradDate": {"gte": "2019-01-01", "lte": "2019-12-31"}}}}`),
})

{% include copy.html %}

결과 페이징하기

결과를 페이징하려면 from과 size 파라미터를 사용하세요. 다음 예제는 학생들을 졸업 날짜 기준으로 정렬해서 결과를 한 번에 두 개씩 가져와요. 첫 번째 요청은 결과의 첫 페이지를 반환하고, 두 번째 요청은 그다음 페이지를 반환해요:

searchResp, err := client.Search(ctx, &opensearchapi.SearchReq{
	Indices: []string{index},
	Params:  &opensearchapi.SearchParams{From: 0, Size: new(2), Sort: []string{"gradDate:asc"}},
})
if err != nil {
	return err
}
nextResp, err := client.Search(ctx, &opensearchapi.SearchReq{
	Indices: []string{index},
	Params:  &opensearchapi.SearchParams{From: 2, Size: new(2), Sort: []string{"gradDate:asc"}},
})
if err != nil {
	return err
}
for i, resp := range []*opensearchapi.SearchResp{searchResp, nextResp} {
	fmt.Printf("Page %d:\n", i+1)
	for _, hit := range resp.Hits.Hits {
		var s Student
		if err := json.Unmarshal(hit.Source, &s); err != nil {
			return err
		}
		out, err := json.Marshal(s)
		if err != nil {
			return err
		}
		fmt.Println("  " + string(out))
	}
}

{% include copy.html %}

from과 size 파라미터는 결과의 첫 몇 페이지를 넘길 때 적합해요. 많은 양의 결과를 페이징하려면 point in time과 search_after를 사용하세요. 자세한 내용은 결과 페이징을 참고하세요.

문서 업데이트하기

doc 필드에 부분 문서를 사용해 문서의 특정 필드를 업데이트할 수 있어요. 지정된 필드만 업데이트돼요:

updateResp, err := client.Doc.Update(ctx, opensearchapi.UpdateReq{
	Index:      index,
	ID:         "1",
	BodyReader: strings.NewReader(`{"doc": {"gpa": 3.92}}`),
})

{% include copy.html %}

문서 삭제하기

다음 코드를 사용해 문서를 삭제할 수 있어요:

deleteResp, err := client.Doc.Delete(ctx, opensearchapi.DeleteReq{
	Index:  index,
	ID:     "3",
	Params: &opensearchapi.DeleteParams{Refresh: "true"},
})

{% include copy.html %}

인덱스 삭제하기

다음 코드를 사용해 인덱스를 삭제할 수 있어요:

deleteIndexResp, err := client.Indices.Delete(ctx, &opensearchapi.IndicesDeleteReq{Indices: []string{index}})

{% include copy.html %}

샘플 프로그램

이 샘플 프로그램은 앞선 섹션의 코드들을 하나로 합친 거예요. Security 플러그인이 활성화된 클러스터에 연결해요. Security 플러그인 없이 클러스터에 연결하려면 // Without security 주석으로 표시된 줄을 변경하세요.

이 샘플 프로그램은 테스트 용도로만 사용해야 해요. 자체 서명 인증서를 사용하는 클러스터에 연결할 수 있도록 코드에 자격 증명을 지정하고 인증서 검증을 비활성화해요. 프로덕션 환경에서는 자격 증명을 안전한 위치에서 불러오고 클러스터의 인증서를 검증하세요. {: .warning}

다음 샘플 프로그램은 클라이언트를 만들고, 인덱스를 생성하고, 문서를 하나씩 또는 벌크로 인덱싱하고, 문서를 검색하고, 문서를 업데이트하고, 문서를 삭제한 다음 인덱스를 삭제해요:

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"
	"strings"

	"github.com/opensearch-project/opensearch-go/v5"
	"github.com/opensearch-project/opensearch-go/v5/opensearchapi"
	"github.com/opensearch-project/opensearch-go/v5/opensearchutil"
)

type Student struct {
	FirstName string  `json:"firstName"`
	LastName  string  `json:"lastName"`
	GPA       float64 `json:"gpa"`
	GradDate  string  `json:"gradDate"`
}

func main() {
	if err := run(); err != nil {
		fmt.Println("Error:", err)
		os.Exit(1)
	}
}

func run() error {
	ctx := context.Background()

	client, err := opensearchapi.NewClient(opensearchapi.Config{
		Client: opensearch.Config{
			// Without security, use http://localhost:9200
			Addresses: []string{"https://localhost:9200"},
			// Without security, remove this line
			InsecureSkipVerify: true,
			// Without security, remove this line
			Username: "admin",
			// Without security, remove this line
			Password:             "<custom-admin-password>",
			DiscoverNodesOnStart: new(false),
		},
	})
	if err != nil {
		return err
	}

	// Create the index
	index := "students"
	fmt.Println("Creating index......")
	body := `{
	  "settings": {
	    "index": {
	      "number_of_shards": 1,
	      "number_of_replicas": 1
	    }
	  },
	  "mappings": {
	    "properties": {
	      "gradDate": { "type": "date", "format": "yyyy-MM-dd" }
	    }
	  }
	}`
	createResp, err := client.Indices.Create(ctx, opensearchapi.IndicesCreateReq{
		Index:      index,
		BodyReader: strings.NewReader(body),
	})
	if err != nil {
		return err
	}
	fmt.Println("Index created:", createResp.Index)

	// Index a document
	fmt.Println("\nIndexing one student......")
	student := Student{FirstName: "John", LastName: "Doe", GPA: 3.89, GradDate: "2022-05-15"}
	indexResp, err := client.Doc.Index(ctx, opensearchapi.IndexReq{
		Index:  index,
		ID:     "1",
		Body:   opensearchutil.NewJSONReader(student),
		Params: &opensearchapi.IndexParams{Refresh: "true"},
	})
	if err != nil {
		return err
	}
	fmt.Printf("Result: %s, id: %s, version: %d\n", indexResp.Result, indexResp.ID, indexResp.Version)

	// Bulk index documents
	fmt.Println("\nIndexing many students......")
	students := []struct {
		id      string
		student Student
	}{
		{"2", Student{FirstName: "Paulo", LastName: "Santos", GPA: 3.93, GradDate: "2021-05-20"}},
		{"3", Student{FirstName: "Shirley", LastName: "Rodriguez", GPA: 3.91, GradDate: "2019-05-10"}},
	}
	var bulkBody strings.Builder
	for _, s := range students {
		doc, err := json.Marshal(s.student)
		if err != nil {
			return err
		}
		fmt.Fprintf(&bulkBody, "{\"index\":{\"_id\":%q}}\n%s\n", s.id, doc)
	}
	bulkResp, err := client.Doc.Bulk(ctx, opensearchapi.BulkReq{
		Index:  index,
		Body:   strings.NewReader(bulkBody.String()),
		Params: &opensearchapi.BulkParams{Refresh: "true"},
	})
	if err != nil {
		return err
	}
	fmt.Println("Errors:", bulkResp.Errors)
	for _, item := range bulkResp.Items {
		fmt.Printf("  %s id: %s\n", *item.Index.Result, *item.Index.ID)
	}

	// Search for all students
	fmt.Println("\nSearching for all students......")
	searchResp, err := client.Search(ctx, &opensearchapi.SearchReq{
		Indices: []string{index},
		Params:  &opensearchapi.SearchParams{From: 0, Size: new(2), Sort: []string{"gradDate:asc"}},
	})
	if err != nil {
		return err
	}
	total, err := searchResp.Hits.Total.TotalHits()
	if err != nil {
		return err
	}
	fmt.Println("Total hits:", total.Value)
	nextResp, err := client.Search(ctx, &opensearchapi.SearchReq{
		Indices: []string{index},
		Params:  &opensearchapi.SearchParams{From: 2, Size: new(2), Sort: []string{"gradDate:asc"}},
	})
	if err != nil {
		return err
	}
	for i, resp := range []*opensearchapi.SearchResp{searchResp, nextResp} {
		fmt.Printf("Page %d:\n", i+1)
		for _, hit := range resp.Hits.Hits {
			var s Student
			if err := json.Unmarshal(hit.Source, &s); err != nil {
				return err
			}
			out, err := json.Marshal(s)
			if err != nil {
				return err
			}
			fmt.Println("  " + string(out))
		}
	}

	// Search for students who graduated in 2019
	fmt.Println("\nSearching for students who graduated in 2019......")
	searchResp, err = client.Search(ctx, &opensearchapi.SearchReq{
		Indices:    []string{index},
		BodyReader: strings.NewReader(`{"query": {"range": {"gradDate": {"gte": "2019-01-01", "lte": "2019-12-31"}}}}`),
	})
	if err != nil {
		return err
	}
	total, err = searchResp.Hits.Total.TotalHits()
	if err != nil {
		return err
	}
	fmt.Println("Total hits:", total.Value)
	for _, hit := range searchResp.Hits.Hits {
		var s Student
		if err := json.Unmarshal(hit.Source, &s); err != nil {
			return err
		}
		out, err := json.Marshal(s)
		if err != nil {
			return err
		}
		fmt.Println("  " + string(out))
	}

	// Update a document
	fmt.Println("\nUpdating a student's GPA......")
	updateResp, err := client.Doc.Update(ctx, opensearchapi.UpdateReq{
		Index:      index,
		ID:         "1",
		BodyReader: strings.NewReader(`{"doc": {"gpa": 3.92}}`),
	})
	if err != nil {
		return err
	}
	fmt.Printf("Result: %s, version: %d\n", updateResp.Result, updateResp.Version)

	// Get the updated document
	getResp, err := client.Doc.Get(ctx, opensearchapi.GetReq{Index: index, ID: "1"})
	if err != nil {
		return err
	}
	var updated Student
	if err := json.Unmarshal(getResp.Source, &updated); err != nil {
		return err
	}
	out, err := json.Marshal(updated)
	if err != nil {
		return err
	}
	fmt.Println("Updated document: " + string(out))

	// Delete a document
	fmt.Println("\nDeleting a student......")
	deleteResp, err := client.Doc.Delete(ctx, opensearchapi.DeleteReq{
		Index:  index,
		ID:     "3",
		Params: &opensearchapi.DeleteParams{Refresh: "true"},
	})
	if err != nil {
		return err
	}
	fmt.Println("Result:", deleteResp.Result)

	// Delete the index
	fmt.Println("\nDeleting the index......")
	deleteIndexResp, err := client.Indices.Delete(ctx, &opensearchapi.IndicesDeleteReq{Indices: []string{index}})
	if err != nil {
		return err
	}
	fmt.Println("Acknowledged:", deleteIndexResp.Acknowledged)

	return nil
}

{% include copy.html %}

프로그램을 실행하면 다음과 같은 출력이 나와요:

Creating index......
Index created: students

Indexing one student......
Result: created, id: 1, version: 1

Indexing many students......
Errors: false
  created id: 2
  created id: 3

Searching for all students......
Total hits: 3
Page 1:
  {"firstName":"Shirley","lastName":"Rodriguez","gpa":3.91,"gradDate":"2019-05-10"}
  {"firstName":"Paulo","lastName":"Santos","gpa":3.93,"gradDate":"2021-05-20"}
Page 2:
  {"firstName":"John","lastName":"Doe","gpa":3.89,"gradDate":"2022-05-15"}

Searching for students who graduated in 2019......
Total hits: 1
  {"firstName":"Shirley","lastName":"Rodriguez","gpa":3.91,"gradDate":"2019-05-10"}

Updating a student's GPA......
Result: updated, version: 2
Updated document: {"firstName":"John","lastName":"Doe","gpa":3.92,"gradDate":"2022-05-15"}

Deleting a student......
Result: deleted

Deleting the index......
Acknowledged: true

관련 문서

더 알아보기 (Learn more)