Repository: milvus-io/milvus-sdk-go
Pull request #139 (2021-07-15 04:19:16)

Add index usage example
Add `CreateIndex` async switch
Add Index related example

Solves: #138 #125 

Signed-off-by: Congqi Xia <congqi.xia@zilliz.com>

sre-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/milvus-io/milvus-sdk-go/pull/139#" title="Author self-approved">congqixia</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=milvus-io%2Fmilvus-sdk-go).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/milvus-io/milvus-sdk-go/blob/master/OWNERS)~~ [congqixia]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
sunby: /lgtm
/approve
sre-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/milvus-io/milvus-sdk-go/pull/139#" title="Author self-approved">congqixia</a>*, *<a href="https://github.com/milvus-io/milvus-sdk-go/pull/139#issuecomment-880379686" title="Approved">sunby</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=milvus-io%2Fmilvus-sdk-go).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/milvus-io/milvus-sdk-go/blob/master/OWNERS)~~ [congqixia,sunby]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/client/client.go b/client/client.go
index 46d0c0a..5433d68 100644
--- a/client/client.go
+++ b/client/client.go
@@ -64,7 +64,7 @@ type Client interface {
 
 	// CreateIndex create index for field of specified collection
 	// currently index naming is not supported, so only one index on vector field is supported
-	CreateIndex(ctx context.Context, collName string, fieldName string, idx entity.Index) error
+	CreateIndex(ctx context.Context, collName string, fieldName string, idx entity.Index, async bool) error
 	// DescribeIndex describe index on collection
 	// currently index naming is not supported, so only one index on vector field is supported
 	DescribeIndex(ctx context.Context, collName string, fieldName string) ([]entity.Index, error)
diff --git a/client/client_grpc_dd.go b/client/client_grpc_dd.go
index b788c68..3a8eb89 100644
--- a/client/client_grpc_dd.go
+++ b/client/client_grpc_dd.go
@@ -536,7 +536,8 @@ func (c *grpcClient) ReleasePartitions(ctx context.Context, collName string, par
 }
 
 // CreateIndex create index for collection
-func (c *grpcClient) CreateIndex(ctx context.Context, collName string, fieldName string, idx entity.Index) error {
+func (c *grpcClient) CreateIndex(ctx context.Context, collName string, fieldName string,
+	idx entity.Index, async bool) error {
 	if c.service == nil {
 		return ErrClientNotReady
 	}
@@ -550,7 +551,26 @@ func (c *grpcClient) CreateIndex(ctx context.Context, collName string, fieldName
 	if err != nil {
 		return err
 	}
-	return handleRespStatus(resp)
+	if err = handleRespStatus(resp); err != nil {
+		return err
+	}
+	if !async { // sync mode, wait index building result
+		for {
+			is, err := c.GetIndexState(ctx, collName, fieldName)
+			if err != nil {
+				return err
+			}
+			switch is {
+			case entity.IndexState(common.IndexState_Failed):
+				return errors.New("index build failed")
+			case entity.IndexState(common.IndexState_Finished):
+				return nil
+			default:
+			}
+			time.Sleep(100 * time.Millisecond) // wait 100ms
+		}
+	}
+	return nil
 }
 
 // DescribeIndex describe index
@@ -615,10 +635,10 @@ func (c *grpcClient) GetIndexState(ctx context.Context, collName string, fieldNa
 	}
 	resp, err := c.service.GetIndexState(ctx, req)
 	if err != nil {
-		return entity.IndexState(common.IndexState_Failed), err
+		return entity.IndexState(common.IndexState_IndexStateNone), err
 	}
 	if err := handleRespStatus(resp.GetStatus()); err != nil {
-		return entity.IndexState(common.IndexState_Failed), err
+		return entity.IndexState(common.IndexState_IndexStateNone), err
 	}
 
 	return entity.IndexState(resp.GetState()), nil
diff --git a/client/client_grpc_tmp.go b/client/client_grpc_tmp.go
new file mode 100644
index 0000000..cc07f12
--- /dev/null
+++ b/client/client_grpc_tmp.go
@@ -0,0 +1,51 @@
+package client
+
+//// Search collection
+//func (c *grpcClient) Search2(ctx context.Context, collName string) {
+//	if c.service == nil {
+//		return
+//	}
+//	req := &server.SearchRequest{
+//		DbName:         "", // reserved
+//		CollectionName: collName,
+//		PartitionNames: []string{},
+//		Dsl:            "", //TODO
+//		DslType:        common.DslType_Dsl,
+//		OutputFields:   []string{},
+//	}
+//	resp, err := c.service.Search(ctx, req)
+//	if err != nil {
+//		return
+//	}
+//	if err := handleRespStatus(resp.GetStatus()); err != nil {
+//		return
+//	}
+//	//resp.Results.
+//}
+//
+//func (c *grpcClient) SearchWithExpression() {
+//
+//}
+//
+//func (c *grpcClient) DslSearch(ctx context.Context, collName string, dsl string, outputFields []string, placeHolders entity.Column) {
+//	if c.service == nil {
+//		return
+//	}
+//	if placeHolders.Len() == 0 {
+//		return
+//	}
+//	searchParams := entity.MapKvPairs(map[string]string{
+//		"metric_type": "L2",
+//		"nprobe":      "10",
+//	})
+//	req := &server.SearchRequest{
+//		DbName:         "", // reserved
+//		CollectionName: collName,
+//		PartitionNames: []string{},
+//		SearchParams:   searchParams,
+//		Dsl:            dsl,
+//		DslType:        common.DslType_Dsl,
+//		OutputFields:   outputFields,
+//	}
+//	c.service.Search(ctx, req)
+//}
diff --git a/entity/genidx/genidx.go b/entity/genidx/genidx.go
index e123c8e..125120f 100644
--- a/entity/genidx/genidx.go
+++ b/entity/genidx/genidx.go
@@ -42,6 +42,7 @@ var _ Index = &Index{{.IdxName}}{}
 // Index{{.IdxName}} idx type for {{.IdxType}}
 type Index{{.IdxName}} struct { //auto generated fields{{range .ConstructParams}}{{with .}}
 	{{.Name}} {{.ParamType}}{{end}}{{end}}
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -63,11 +64,13 @@ func(i *Index{{.IdxName}}) SupportBinary() bool {
 func(i *Index{{.IdxName}}) Params() map[string]string {
 	return map[string]string {//auto generated mapping {{range .ConstructParams}}{{with .}}
 		"{{.Name}}": fmt.Sprintf("%v",i.{{.Name}}),{{end}}{{end}}
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndex{{.IdxName}} create index with contruction parameters
-func NewIndex{{.IdxName}}({{range .ConstructParams}}{{with .}}
+func NewIndex{{.IdxName}}(metricType MetricType, {{range .ConstructParams}}{{with .}}
 	{{.Name}} {{.ParamType}},
 {{end}}{{end}}) (*Index{{.IdxName}}, error) {
 	// auto generate parameters validation code, if any{{range .ConstructParams}}{{with .}}
@@ -76,6 +79,7 @@ func NewIndex{{.IdxName}}({{range .ConstructParams}}{{with .}}
 	return &Index{{.IdxName}}{ {{range .ConstructParams}}{{with .}}
 	//auto generated setting
 	{{.Name}}: {{.Name}},{{end}}{{end}}
+	metricType: metricType,
 	}, nil
 }
 {{end}}{{end}}
@@ -100,10 +104,13 @@ func TestIndex{{.IdxName}}(t *testing.T){
 	{{range .ConstructParams}}{{with.}}
 	var {{.Name}} {{.ParamType}}{{end}}{{end}}
 
+	{{if SContains $idx.IdxName "Bin" }}mt := HAMMING{{else}}mt := L2{{end}}
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		{{range $i, $example := .ValidExamples}}
 		{{$example}}
-		idx{{$i}}, err := NewIndex{{$idx.IdxName}}({{range $idx.ConstructParams}}{{with.}}
+		idx{{$i}}, err := NewIndex{{$idx.IdxName}}(mt, {{range $idx.ConstructParams}}{{with.}}
 			{{.Name}},{{end}}{{end}}
 		)
 		assert.Nil(t, err)
@@ -118,7 +125,7 @@ func TestIndex{{.IdxName}}(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		{{range $i, $example := .InvalidExamples}}
 		{{$example}}
-		idx{{$i}}, err := NewIndex{{$idx.IdxName}}({{range $idx.ConstructParams}}{{with.}}
+		idx{{$i}}, err := NewIndex{{$idx.IdxName}}(mt, {{range $idx.ConstructParams}}{{with.}}
 			{{.Name}},{{end}}{{end}}
 		)
 		assert.NotNil(t, err)
diff --git a/entity/indexes_gen.go b/entity/indexes_gen.go
index fc5989a..18da55b 100755
--- a/entity/indexes_gen.go
+++ b/entity/indexes_gen.go
@@ -1,5 +1,5 @@
 // Code generated by go generate; DO NOT EDIT
-// This file is generated by go generate at 2021-07-15 10:38:56.086006767 +0800 CST m=+0.005470307
+// This file is generated by go generate at 2021-07-15 12:08:49.007744289 +0800 CST m=+0.005951592
 
 //Package entity defineds entities used in sdk
 package entity
@@ -16,6 +16,7 @@ var _ Index = &IndexFlat{}
 // IndexFlat idx type for FLAT
 type IndexFlat struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -37,11 +38,13 @@ func(i *IndexFlat) SupportBinary() bool {
 func(i *IndexFlat) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexFlat create index with contruction parameters
-func NewIndexFlat(
+func NewIndexFlat(metricType MetricType, 
 	nlist int,
 ) (*IndexFlat, error) {
 	// auto generate parameters validation code, if any
@@ -55,6 +58,7 @@ func NewIndexFlat(
 	return &IndexFlat{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -64,6 +68,7 @@ var _ Index = &IndexBinFlat{}
 // IndexBinFlat idx type for BIN_FLAT
 type IndexBinFlat struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -85,11 +90,13 @@ func(i *IndexBinFlat) SupportBinary() bool {
 func(i *IndexBinFlat) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexBinFlat create index with contruction parameters
-func NewIndexBinFlat(
+func NewIndexBinFlat(metricType MetricType, 
 	nlist int,
 ) (*IndexBinFlat, error) {
 	// auto generate parameters validation code, if any
@@ -103,6 +110,7 @@ func NewIndexBinFlat(
 	return &IndexBinFlat{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -112,6 +120,7 @@ var _ Index = &IndexIvfFlat{}
 // IndexIvfFlat idx type for IVF_FLAT
 type IndexIvfFlat struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -133,11 +142,13 @@ func(i *IndexIvfFlat) SupportBinary() bool {
 func(i *IndexIvfFlat) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexIvfFlat create index with contruction parameters
-func NewIndexIvfFlat(
+func NewIndexIvfFlat(metricType MetricType, 
 	nlist int,
 ) (*IndexIvfFlat, error) {
 	// auto generate parameters validation code, if any
@@ -151,6 +162,7 @@ func NewIndexIvfFlat(
 	return &IndexIvfFlat{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -160,6 +172,7 @@ var _ Index = &IndexBinIvfFlat{}
 // IndexBinIvfFlat idx type for BIN_IVF_FLAT
 type IndexBinIvfFlat struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -181,11 +194,13 @@ func(i *IndexBinIvfFlat) SupportBinary() bool {
 func(i *IndexBinIvfFlat) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexBinIvfFlat create index with contruction parameters
-func NewIndexBinIvfFlat(
+func NewIndexBinIvfFlat(metricType MetricType, 
 	nlist int,
 ) (*IndexBinIvfFlat, error) {
 	// auto generate parameters validation code, if any
@@ -199,6 +214,7 @@ func NewIndexBinIvfFlat(
 	return &IndexBinIvfFlat{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -208,6 +224,7 @@ var _ Index = &IndexIvfSQ8{}
 // IndexIvfSQ8 idx type for IVF_SQ8
 type IndexIvfSQ8 struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -229,11 +246,13 @@ func(i *IndexIvfSQ8) SupportBinary() bool {
 func(i *IndexIvfSQ8) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexIvfSQ8 create index with contruction parameters
-func NewIndexIvfSQ8(
+func NewIndexIvfSQ8(metricType MetricType, 
 	nlist int,
 ) (*IndexIvfSQ8, error) {
 	// auto generate parameters validation code, if any
@@ -247,6 +266,7 @@ func NewIndexIvfSQ8(
 	return &IndexIvfSQ8{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -256,6 +276,7 @@ var _ Index = &IndexIvfSQ8H{}
 // IndexIvfSQ8H idx type for IVF_SQ8_HYBRID
 type IndexIvfSQ8H struct { //auto generated fields
 	nlist int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -277,11 +298,13 @@ func(i *IndexIvfSQ8H) SupportBinary() bool {
 func(i *IndexIvfSQ8H) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"nlist": fmt.Sprintf("%v",i.nlist),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexIvfSQ8H create index with contruction parameters
-func NewIndexIvfSQ8H(
+func NewIndexIvfSQ8H(metricType MetricType, 
 	nlist int,
 ) (*IndexIvfSQ8H, error) {
 	// auto generate parameters validation code, if any
@@ -295,6 +318,7 @@ func NewIndexIvfSQ8H(
 	return &IndexIvfSQ8H{ 
 	//auto generated setting
 	nlist: nlist,
+	metricType: metricType,
 	}, nil
 }
 
@@ -306,6 +330,7 @@ type IndexIvfPQ struct { //auto generated fields
 	nlist int
 	m int
 	nbits int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -329,11 +354,13 @@ func(i *IndexIvfPQ) Params() map[string]string {
 		"nlist": fmt.Sprintf("%v",i.nlist),
 		"m": fmt.Sprintf("%v",i.m),
 		"nbits": fmt.Sprintf("%v",i.nbits),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexIvfPQ create index with contruction parameters
-func NewIndexIvfPQ(
+func NewIndexIvfPQ(metricType MetricType, 
 	nlist int,
 
 	m int,
@@ -364,6 +391,7 @@ func NewIndexIvfPQ(
 	m: m,
 	//auto generated setting
 	nbits: nbits,
+	metricType: metricType,
 	}, nil
 }
 
@@ -376,6 +404,7 @@ type IndexRNSG struct { //auto generated fields
 	candidate_pool_size int
 	search_length int
 	knng int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -400,11 +429,13 @@ func(i *IndexRNSG) Params() map[string]string {
 		"candidate_pool_size": fmt.Sprintf("%v",i.candidate_pool_size),
 		"search_length": fmt.Sprintf("%v",i.search_length),
 		"knng": fmt.Sprintf("%v",i.knng),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexRNSG create index with contruction parameters
-func NewIndexRNSG(
+func NewIndexRNSG(metricType MetricType, 
 	out_degree int,
 
 	candidate_pool_size int,
@@ -451,6 +482,7 @@ func NewIndexRNSG(
 	search_length: search_length,
 	//auto generated setting
 	knng: knng,
+	metricType: metricType,
 	}, nil
 }
 
@@ -461,6 +493,7 @@ var _ Index = &IndexHNSW{}
 type IndexHNSW struct { //auto generated fields
 	M int
 	efConstruction int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -483,11 +516,13 @@ func(i *IndexHNSW) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"M": fmt.Sprintf("%v",i.M),
 		"efConstruction": fmt.Sprintf("%v",i.efConstruction),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexHNSW create index with contruction parameters
-func NewIndexHNSW(
+func NewIndexHNSW(metricType MetricType, 
 	M int,
 
 	efConstruction int,
@@ -512,6 +547,7 @@ func NewIndexHNSW(
 	M: M,
 	//auto generated setting
 	efConstruction: efConstruction,
+	metricType: metricType,
 	}, nil
 }
 
@@ -522,6 +558,7 @@ var _ Index = &IndexRHNSWFlat{}
 type IndexRHNSWFlat struct { //auto generated fields
 	M int
 	efConstruction int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -544,11 +581,13 @@ func(i *IndexRHNSWFlat) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"M": fmt.Sprintf("%v",i.M),
 		"efConstruction": fmt.Sprintf("%v",i.efConstruction),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexRHNSWFlat create index with contruction parameters
-func NewIndexRHNSWFlat(
+func NewIndexRHNSWFlat(metricType MetricType, 
 	M int,
 
 	efConstruction int,
@@ -573,6 +612,7 @@ func NewIndexRHNSWFlat(
 	M: M,
 	//auto generated setting
 	efConstruction: efConstruction,
+	metricType: metricType,
 	}, nil
 }
 
@@ -584,6 +624,7 @@ type IndexRHNSW_PQ struct { //auto generated fields
 	M int
 	efConstruction int
 	PQM int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -607,11 +648,13 @@ func(i *IndexRHNSW_PQ) Params() map[string]string {
 		"M": fmt.Sprintf("%v",i.M),
 		"efConstruction": fmt.Sprintf("%v",i.efConstruction),
 		"PQM": fmt.Sprintf("%v",i.PQM),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexRHNSW_PQ create index with contruction parameters
-func NewIndexRHNSW_PQ(
+func NewIndexRHNSW_PQ(metricType MetricType, 
 	M int,
 
 	efConstruction int,
@@ -642,6 +685,7 @@ func NewIndexRHNSW_PQ(
 	efConstruction: efConstruction,
 	//auto generated setting
 	PQM: PQM,
+	metricType: metricType,
 	}, nil
 }
 
@@ -652,6 +696,7 @@ var _ Index = &IndexRHNSW_SQ{}
 type IndexRHNSW_SQ struct { //auto generated fields
 	M int
 	efConstruction int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -674,11 +719,13 @@ func(i *IndexRHNSW_SQ) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"M": fmt.Sprintf("%v",i.M),
 		"efConstruction": fmt.Sprintf("%v",i.efConstruction),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexRHNSW_SQ create index with contruction parameters
-func NewIndexRHNSW_SQ(
+func NewIndexRHNSW_SQ(metricType MetricType, 
 	M int,
 
 	efConstruction int,
@@ -703,6 +750,7 @@ func NewIndexRHNSW_SQ(
 	M: M,
 	//auto generated setting
 	efConstruction: efConstruction,
+	metricType: metricType,
 	}, nil
 }
 
@@ -714,6 +762,7 @@ type IndexIvfHNSW struct { //auto generated fields
 	nlist int
 	M int
 	efConstruction int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -737,11 +786,13 @@ func(i *IndexIvfHNSW) Params() map[string]string {
 		"nlist": fmt.Sprintf("%v",i.nlist),
 		"M": fmt.Sprintf("%v",i.M),
 		"efConstruction": fmt.Sprintf("%v",i.efConstruction),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexIvfHNSW create index with contruction parameters
-func NewIndexIvfHNSW(
+func NewIndexIvfHNSW(metricType MetricType, 
 	nlist int,
 
 	M int,
@@ -777,6 +828,7 @@ func NewIndexIvfHNSW(
 	M: M,
 	//auto generated setting
 	efConstruction: efConstruction,
+	metricType: metricType,
 	}, nil
 }
 
@@ -786,6 +838,7 @@ var _ Index = &IndexANNOY{}
 // IndexANNOY idx type for ANNOY
 type IndexANNOY struct { //auto generated fields
 	n_trees int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -807,11 +860,13 @@ func(i *IndexANNOY) SupportBinary() bool {
 func(i *IndexANNOY) Params() map[string]string {
 	return map[string]string {//auto generated mapping 
 		"n_trees": fmt.Sprintf("%v",i.n_trees),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexANNOY create index with contruction parameters
-func NewIndexANNOY(
+func NewIndexANNOY(metricType MetricType, 
 	n_trees int,
 ) (*IndexANNOY, error) {
 	// auto generate parameters validation code, if any
@@ -825,6 +880,7 @@ func NewIndexANNOY(
 	return &IndexANNOY{ 
 	//auto generated setting
 	n_trees: n_trees,
+	metricType: metricType,
 	}, nil
 }
 
@@ -836,6 +892,7 @@ type IndexNGTPANNG struct { //auto generated fields
 	edge_size int
 	forcedly_pruned_edge_size int
 	selectively_pruned_edge_size int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -859,11 +916,13 @@ func(i *IndexNGTPANNG) Params() map[string]string {
 		"edge_size": fmt.Sprintf("%v",i.edge_size),
 		"forcedly_pruned_edge_size": fmt.Sprintf("%v",i.forcedly_pruned_edge_size),
 		"selectively_pruned_edge_size": fmt.Sprintf("%v",i.selectively_pruned_edge_size),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexNGTPANNG create index with contruction parameters
-func NewIndexNGTPANNG(
+func NewIndexNGTPANNG(metricType MetricType, 
 	edge_size int,
 
 	forcedly_pruned_edge_size int,
@@ -899,6 +958,7 @@ func NewIndexNGTPANNG(
 	forcedly_pruned_edge_size: forcedly_pruned_edge_size,
 	//auto generated setting
 	selectively_pruned_edge_size: selectively_pruned_edge_size,
+	metricType: metricType,
 	}, nil
 }
 
@@ -910,6 +970,7 @@ type IndexNGTONNG struct { //auto generated fields
 	edge_size int
 	outgoing_edge_size int
 	incoming_edge_size int
+	metricType MetricType
 }
 
 // Name returns index type name, implementing Index interface
@@ -933,11 +994,13 @@ func(i *IndexNGTONNG) Params() map[string]string {
 		"edge_size": fmt.Sprintf("%v",i.edge_size),
 		"outgoing_edge_size": fmt.Sprintf("%v",i.outgoing_edge_size),
 		"incoming_edge_size": fmt.Sprintf("%v",i.incoming_edge_size),
+		"index_type": string(i.IndexType()),
+		"metric_type": string(i.metricType),
 	}
 }
 
 // NewIndexNGTONNG create index with contruction parameters
-func NewIndexNGTONNG(
+func NewIndexNGTONNG(metricType MetricType, 
 	edge_size int,
 
 	outgoing_edge_size int,
@@ -973,6 +1036,7 @@ func NewIndexNGTONNG(
 	outgoing_edge_size: outgoing_edge_size,
 	//auto generated setting
 	incoming_edge_size: incoming_edge_size,
+	metricType: metricType,
 	}, nil
 }
 
diff --git a/entity/indexes_search_param_gen.go b/entity/indexes_search_param_gen.go
index 16f74e4..67f8d5e 100755
--- a/entity/indexes_search_param_gen.go
+++ b/entity/indexes_search_param_gen.go
@@ -1,5 +1,5 @@
 // Code generated by go generate; DO NOT EDIT
-// This file is generated by go generate at 2021-07-15 10:38:56.086006767 +0800 CST m=+0.005470307
+// This file is generated by go generate at 2021-07-15 12:08:49.007744289 +0800 CST m=+0.005951592
 
 //Package entity defineds entities used in sdk
 package entity
@@ -9,6 +9,7 @@ import (
 	"fmt"
 )
 
+
 var _ SearchParam = &IndexFlatSearchParam{}
 
 // IndexFlatSearchParam search param struct for index type FLAT
@@ -17,9 +18,9 @@ type IndexFlatSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexFlatSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexFlatSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -34,10 +35,10 @@ func NewIndexFlatSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexFlatSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexFlatSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -49,9 +50,9 @@ type IndexBinFlatSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexBinFlatSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexBinFlatSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -66,10 +67,10 @@ func NewIndexBinFlatSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexBinFlatSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexBinFlatSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -81,9 +82,9 @@ type IndexIvfFlatSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexIvfFlatSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexIvfFlatSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -98,10 +99,10 @@ func NewIndexIvfFlatSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexIvfFlatSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexIvfFlatSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -113,9 +114,9 @@ type IndexBinIvfFlatSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexBinIvfFlatSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexBinIvfFlatSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -130,10 +131,10 @@ func NewIndexBinIvfFlatSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexBinIvfFlatSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexBinIvfFlatSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -145,9 +146,9 @@ type IndexIvfSQ8SearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexIvfSQ8SearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexIvfSQ8SearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -162,10 +163,10 @@ func NewIndexIvfSQ8SearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexIvfSQ8SearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexIvfSQ8SearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -177,9 +178,9 @@ type IndexIvfSQ8HSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexIvfSQ8HSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexIvfSQ8HSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -194,10 +195,10 @@ func NewIndexIvfSQ8HSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexIvfSQ8HSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexIvfSQ8HSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -209,9 +210,9 @@ type IndexIvfPQSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexIvfPQSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
+func(i *IndexIvfPQSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
 	}
 }
 
@@ -226,10 +227,10 @@ func NewIndexIvfPQSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
-	return &IndexIvfPQSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
+	
+	return &IndexIvfPQSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
 	}, nil
 }
 
@@ -241,9 +242,9 @@ type IndexRNSGSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexRNSGSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"search_length": fmt.Sprintf("%v", i.search_length),
+func(i *IndexRNSGSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"search_length": fmt.Sprintf("%v",i.search_length),
 	}
 }
 
@@ -258,10 +259,10 @@ func NewIndexRNSGSearchParam(
 	if search_length > 300 {
 		return nil, errors.New("search_length not valid")
 	}
-
-	return &IndexRNSGSearchParam{
-		//auto generated setting
-		search_length: search_length,
+	
+	return &IndexRNSGSearchParam{ 
+	//auto generated setting
+	search_length: search_length,
 	}, nil
 }
 
@@ -273,9 +274,9 @@ type IndexHNSWSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexHNSWSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"ef": fmt.Sprintf("%v", i.ef),
+func(i *IndexHNSWSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"ef": fmt.Sprintf("%v",i.ef),
 	}
 }
 
@@ -290,10 +291,10 @@ func NewIndexHNSWSearchParam(
 	if ef > 32768 {
 		return nil, errors.New("ef not valid")
 	}
-
-	return &IndexHNSWSearchParam{
-		//auto generated setting
-		ef: ef,
+	
+	return &IndexHNSWSearchParam{ 
+	//auto generated setting
+	ef: ef,
 	}, nil
 }
 
@@ -305,9 +306,9 @@ type IndexRHNSWFlatSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexRHNSWFlatSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"ef": fmt.Sprintf("%v", i.ef),
+func(i *IndexRHNSWFlatSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"ef": fmt.Sprintf("%v",i.ef),
 	}
 }
 
@@ -322,10 +323,10 @@ func NewIndexRHNSWFlatSearchParam(
 	if ef > 32768 {
 		return nil, errors.New("ef not valid")
 	}
-
-	return &IndexRHNSWFlatSearchParam{
-		//auto generated setting
-		ef: ef,
+	
+	return &IndexRHNSWFlatSearchParam{ 
+	//auto generated setting
+	ef: ef,
 	}, nil
 }
 
@@ -337,9 +338,9 @@ type IndexRHNSW_PQSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexRHNSW_PQSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"ef": fmt.Sprintf("%v", i.ef),
+func(i *IndexRHNSW_PQSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"ef": fmt.Sprintf("%v",i.ef),
 	}
 }
 
@@ -354,10 +355,10 @@ func NewIndexRHNSW_PQSearchParam(
 	if ef > 32768 {
 		return nil, errors.New("ef not valid")
 	}
-
-	return &IndexRHNSW_PQSearchParam{
-		//auto generated setting
-		ef: ef,
+	
+	return &IndexRHNSW_PQSearchParam{ 
+	//auto generated setting
+	ef: ef,
 	}, nil
 }
 
@@ -369,9 +370,9 @@ type IndexRHNSW_SQSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexRHNSW_SQSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"ef": fmt.Sprintf("%v", i.ef),
+func(i *IndexRHNSW_SQSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"ef": fmt.Sprintf("%v",i.ef),
 	}
 }
 
@@ -386,10 +387,10 @@ func NewIndexRHNSW_SQSearchParam(
 	if ef > 32768 {
 		return nil, errors.New("ef not valid")
 	}
-
-	return &IndexRHNSW_SQSearchParam{
-		//auto generated setting
-		ef: ef,
+	
+	return &IndexRHNSW_SQSearchParam{ 
+	//auto generated setting
+	ef: ef,
 	}, nil
 }
 
@@ -398,14 +399,14 @@ var _ SearchParam = &IndexIvfHNSWSearchParam{}
 // IndexIvfHNSWSearchParam search param struct for index type IVF_HNSW
 type IndexIvfHNSWSearchParam struct { //auto generated fields
 	nprobe int
-	ef     int
+	ef int
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexIvfHNSWSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"nprobe": fmt.Sprintf("%v", i.nprobe),
-		"ef":     fmt.Sprintf("%v", i.ef),
+func(i *IndexIvfHNSWSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"nprobe": fmt.Sprintf("%v",i.nprobe),
+		"ef": fmt.Sprintf("%v",i.ef),
 	}
 }
 
@@ -422,19 +423,19 @@ func NewIndexIvfHNSWSearchParam(
 	if nprobe > 65536 {
 		return nil, errors.New("nprobe not valid")
 	}
-
+	
 	if ef < 1 {
 		return nil, errors.New("ef not valid")
 	}
 	if ef > 32768 {
 		return nil, errors.New("ef not valid")
 	}
-
-	return &IndexIvfHNSWSearchParam{
-		//auto generated setting
-		nprobe: nprobe,
-		//auto generated setting
-		ef: ef,
+	
+	return &IndexIvfHNSWSearchParam{ 
+	//auto generated setting
+	nprobe: nprobe,
+	//auto generated setting
+	ef: ef,
 	}, nil
 }
 
@@ -446,9 +447,9 @@ type IndexANNOYSearchParam struct { //auto generated fields
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexANNOYSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"search_k": fmt.Sprintf("%v", i.search_k),
+func(i *IndexANNOYSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"search_k": fmt.Sprintf("%v",i.search_k),
 	}
 }
 
@@ -457,10 +458,11 @@ func NewIndexANNOYSearchParam(
 	search_k int,
 ) (*IndexANNOYSearchParam, error) {
 	// auto generate parameters validation code, if any
-
-	return &IndexANNOYSearchParam{
-		//auto generated setting
-		search_k: search_k,
+	
+	
+	return &IndexANNOYSearchParam{ 
+	//auto generated setting
+	search_k: search_k,
 	}, nil
 }
 
@@ -469,14 +471,14 @@ var _ SearchParam = &IndexNGTPANNGSearchParam{}
 // IndexNGTPANNGSearchParam search param struct for index type NGT_PANNG
 type IndexNGTPANNGSearchParam struct { //auto generated fields
 	max_search_edges int
-	epsilon          float64
+	epsilon float64
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexNGTPANNGSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"max_search_edges": fmt.Sprintf("%v", i.max_search_edges),
-		"epsilon":          fmt.Sprintf("%v", i.epsilon),
+func(i *IndexNGTPANNGSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"max_search_edges": fmt.Sprintf("%v",i.max_search_edges),
+		"epsilon": fmt.Sprintf("%v",i.epsilon),
 	}
 }
 
@@ -493,19 +495,19 @@ func NewIndexNGTPANNGSearchParam(
 	if max_search_edges > 200 {
 		return nil, errors.New("max_search_edges not valid")
 	}
-
+	
 	if epsilon < -1.0 {
 		return nil, errors.New("epsilon not valid")
 	}
 	if epsilon > 1.0 {
 		return nil, errors.New("epsilon not valid")
 	}
-
-	return &IndexNGTPANNGSearchParam{
-		//auto generated setting
-		max_search_edges: max_search_edges,
-		//auto generated setting
-		epsilon: epsilon,
+	
+	return &IndexNGTPANNGSearchParam{ 
+	//auto generated setting
+	max_search_edges: max_search_edges,
+	//auto generated setting
+	epsilon: epsilon,
 	}, nil
 }
 
@@ -514,14 +516,14 @@ var _ SearchParam = &IndexNGTONNGSearchParam{}
 // IndexNGTONNGSearchParam search param struct for index type NGT_ONNG
 type IndexNGTONNGSearchParam struct { //auto generated fields
 	max_search_edges int
-	epsilon          float64
+	epsilon float64
 }
 
 // Params returns index construction params, implementing Index interface
-func (i *IndexNGTONNGSearchParam) Params() map[string]string {
-	return map[string]string{ //auto generated mapping
-		"max_search_edges": fmt.Sprintf("%v", i.max_search_edges),
-		"epsilon":          fmt.Sprintf("%v", i.epsilon),
+func(i *IndexNGTONNGSearchParam) Params() map[string]string {
+	return map[string]string {//auto generated mapping 
+		"max_search_edges": fmt.Sprintf("%v",i.max_search_edges),
+		"epsilon": fmt.Sprintf("%v",i.epsilon),
 	}
 }
 
@@ -538,18 +540,19 @@ func NewIndexNGTONNGSearchParam(
 	if max_search_edges > 200 {
 		return nil, errors.New("max_search_edges not valid")
 	}
-
+	
 	if epsilon < -1.0 {
 		return nil, errors.New("epsilon not valid")
 	}
 	if epsilon > 1.0 {
 		return nil, errors.New("epsilon not valid")
 	}
-
-	return &IndexNGTONNGSearchParam{
-		//auto generated setting
-		max_search_edges: max_search_edges,
-		//auto generated setting
-		epsilon: epsilon,
+	
+	return &IndexNGTONNGSearchParam{ 
+	//auto generated setting
+	max_search_edges: max_search_edges,
+	//auto generated setting
+	epsilon: epsilon,
 	}, nil
 }
+
diff --git a/examples/README.md b/examples/README.md
index 0367c56..1ce9f9d 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -4,4 +4,4 @@ here is some list to demonstrate the usage of `milvus-sdk-go`
 
 - [Basic Usage](basic/basic.go) Shows some basic DDL(data definition language) like operations. Create collection, create partitions...
 - [Insert and Search](insert/insert.go) Insert & search example, parses [films.csv](films.csv) and insert into collection and do searching
-- Index example placeholder for Index related creation/search example, maybe time consumption will be compared as well
+- [Index building](index/index.go) Index related creation/search example, time consumption compared as well
diff --git a/examples/index/index.go b/examples/index/index.go
new file mode 100644
index 0000000..d53f96b
--- /dev/null
+++ b/examples/index/index.go
@@ -0,0 +1,232 @@
+package main
+
+import (
+	"context"
+	"encoding/csv"
+	"fmt"
+	"log"
+	"os"
+	"strconv"
+	"strings"
+	"time"
+
+	"github.com/milvus-io/milvus-sdk-go/client"
+	"github.com/milvus-io/milvus-sdk-go/entity"
+)
+
+func main() {
+	// Milvus instance proxy address, may verify in your env/settings
+	milvusAddr := `localhost:19530`
+
+	// setup context for client creation, use 2 seconds here
+	ctx := context.Background()
+	ctx, cancel := context.WithTimeout(ctx, 2*time.Second)
+	defer cancel()
+
+	c, err := client.NewGrpcClient(ctx, milvusAddr)
+	if err != nil {
+		// handling error and exit, to make example simple here
+		log.Fatal("failed to connect to milvus:", err.Error())
+	}
+	// in a main func, remember to close the client
+	defer c.Close()
+
+	// here is the collection name we use in this example
+	collectionName := `gosdk_index_example`
+
+	has, err := c.HasCollection(ctx, collectionName)
+	if err != nil {
+		log.Fatal("failed to check whether collection exists:", err.Error())
+	}
+	if has {
+		// collection with same name exist, clean up mess
+		_ = c.DropCollection(ctx, collectionName)
+	}
+
+	// define collection schema, see film.csv
+	schema := &entity.Schema{
+		CollectionName: collectionName,
+		Description:    "this is the example collection for inser and search",
+		AutoID:         false,
+		Fields: []*entity.Field{
+			{
+				Name:       "ID",
+				DataType:   entity.FieldTypeInt64, // int64 only for now
+				PrimaryKey: true,
+				AutoID:     false,
+			},
+			{
+				Name:       "Year",
+				DataType:   entity.FieldTypeInt32,
+				PrimaryKey: false,
+				AutoID:     false,
+			},
+			{
+				Name:     "Vector",
+				DataType: entity.FieldTypeFloatVector,
+				TypeParams: map[string]string{
+					"dim": "8",
+				},
+			},
+		},
+	}
+
+	err = c.CreateCollection(ctx, schema, 1) // only 1 shard
+	if err != nil {
+		log.Fatal("failed to create collection:", err.Error())
+	}
+
+	films, err := loadFilmCSV()
+	if err != nil {
+		log.Fatal("failed to load film data csv:", err.Error())
+	}
+
+	// row-base covert to column-base
+	ids := make([]int64, 0, len(films))
+	years := make([]int32, 0, len(films))
+	vectors := make([][]float32, 0, len(films))
+	// string field is not supported yet
+	idTitle := make(map[int64]string)
+	for idx, film := range films {
+		ids = append(ids, film.ID)
+		idTitle[film.ID] = film.Title
+		years = append(years, film.Year)
+		vectors = append(vectors, films[idx].Vector[:]) // prevent same vector
+	}
+	idColumn := entity.NewColumnInt64("ID", ids)
+	yearColumn := entity.NewColumnInt32("Year", years)
+	vectorColumn := entity.NewColumnFloatVector("Vector", 8, vectors)
+
+	// insert into default partition
+	_, err = c.Insert(ctx, collectionName, "", idColumn, yearColumn, vectorColumn)
+	if err != nil {
+		log.Fatal("failed to insert film data:", err.Error())
+	}
+	log.Println("insert completed")
+	ctx, cancel = context.WithTimeout(context.Background(), time.Second*120)
+	defer cancel()
+	err = c.Flush(ctx, collectionName, false)
+	if err != nil {
+		log.Fatal("failed to flush collection:", err.Error())
+	}
+	log.Println("flush completed")
+
+	// load collection with async=false
+	err = c.LoadCollection(ctx, collectionName, false)
+	if err != nil {
+		log.Fatal("failed to load collection:", err.Error())
+	}
+	log.Println("load collection completed")
+
+	searchFilm := films[0] // use first fim to search
+	vector := entity.FloatVector(searchFilm.Vector[:])
+	sp, _ := entity.NewIndexFlatSearchParam(10)
+	start := time.Now()
+	sr, err := c.Search(ctx, collectionName, []string{}, "Year > 1990", []string{"ID"}, []entity.Vector{vector}, "Vector",
+		entity.L2, 10, sp)
+	if err != nil {
+		log.Fatal("fail to search collection:", err.Error())
+	}
+	log.Println("search without index time elasped:", time.Since(start))
+	for _, result := range sr {
+		var idColumn *entity.ColumnInt64
+		for _, field := range result.Fields {
+			if field.Name() == "ID" {
+				c, ok := field.(*entity.ColumnInt64)
+				if ok {
+					idColumn = c
+				}
+			}
+		}
+		if idColumn == nil {
+			log.Fatal("result field not math")
+		}
+		for i := 0; i < result.ResultCount; i++ {
+			id, err := idColumn.ValueByIdx(i)
+			if err != nil {
+				log.Fatal(err.Error())
+			}
+			title := idTitle[id]
+			fmt.Printf("file id: %d title: %s scores: %f\n", id, title, result.Scores[i])
+		}
+	}
+
+	// Now add index
+	idx, err := entity.NewIndexIvfFlat(entity.L2, 2)
+	if err != nil {
+		log.Fatal("fail to create ivf flat index:", err.Error())
+	}
+	err = c.CreateIndex(ctx, collectionName, "Vector", idx, false)
+	if err != nil {
+		log.Fatal("fail to create index:", err.Error())
+	}
+
+	// do search again
+	start = time.Now()
+	sr, err = c.Search(ctx, collectionName, []string{}, "Year > 1990", []string{"ID"}, []entity.Vector{vector}, "Vector",
+		entity.L2, 10, sp)
+	if err != nil {
+		log.Fatal("fail to search collection:", err.Error())
+	}
+	log.Println("search with index time elasped:", time.Since(start))
+
+	// clean up
+	_ = c.DropCollection(ctx, collectionName)
+}
+
+type film struct {
+	ID     int64
+	Title  string
+	Year   int32
+	Vector [8]float32 // fix lenght array
+}
+
+func loadFilmCSV() ([]film, error) {
+	f, err := os.Open("../films.csv") // assume you are in examples/insert folder, if not, please change the path
+	if err != nil {
+		return []film{}, err
+	}
+	r := csv.NewReader(f)
+	raw, err := r.ReadAll()
+	if err != nil {
+		return []film{}, err
+	}
+	films := make([]film, 0, len(raw))
+	for _, line := range raw {
+		if len(line) < 4 { // insuffcient column
+			continue
+		}
+		fi := film{}
+		// ID
+		v, err := strconv.ParseInt(line[0], 10, 64)
+		if err != nil {
+			continue
+		}
+		fi.ID = v
+		// Title
+		fi.Title = line[1]
+		// Year
+		v, err = strconv.ParseInt(line[2], 10, 64)
+		if err != nil {
+			continue
+		}
+		fi.Year = int32(v)
+		// Vector
+		vectorStr := strings.ReplaceAll(line[3], "[", "")
+		vectorStr = strings.ReplaceAll(vectorStr, "]", "")
+		parts := strings.Split(vectorStr, ",")
+		if len(parts) != 8 { // dim must be 8
+			continue
+		}
+		for idx, part := range parts {
+			part = strings.TrimSpace(part)
+			v, err := strconv.ParseFloat(part, 32)
+			if err != nil {
+				continue
+			}
+			fi.Vector[idx] = float32(v)
+		}
+		films = append(films, fi)
+	}
+	return films, nil
+}


Test patch:
diff --git a/client/client_grpc_dd_test.go b/client/client_grpc_dd_test.go
index 5c5b41e..0b693d9 100644
--- a/client/client_grpc_dd_test.go
+++ b/client/client_grpc_dd_test.go
@@ -764,7 +764,7 @@ func TestGrpcClientCreateIndex(t *testing.T) {
 		"metric_type": "IP",
 	})
 
-	assert.Nil(t, c.CreateIndex(ctx, testCollectionName, "vector", idx))
+	assert.Nil(t, c.CreateIndex(ctx, testCollectionName, "vector", idx, true))
 }
 
 func TestGrpcClientDropIndex(t *testing.T) {
diff --git a/entity/indexes_gen_test.go b/entity/indexes_gen_test.go
index d409a87..14e6eb2 100755
--- a/entity/indexes_gen_test.go
+++ b/entity/indexes_gen_test.go
@@ -1,5 +1,5 @@
 // Code generated by go generate; DO NOT EDIT
-// This file is generated by go generate at 2021-07-15 10:38:56.086006767 +0800 CST m=+0.005470307
+// This file is generated by go generate at 2021-07-15 12:08:49.007744289 +0800 CST m=+0.005951592
 
 //Package entity defineds entities used in sdk
 package entity
@@ -15,10 +15,13 @@ func TestIndexFlat(t *testing.T){
 	
 	var nlist int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 2048
-		idx0, err := NewIndexFlat(
+		idx0, err := NewIndexFlat(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -33,14 +36,14 @@ func TestIndexFlat(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexFlat(
+		idx0, err := NewIndexFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexFlat(
+		idx1, err := NewIndexFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -53,10 +56,13 @@ func TestIndexBinFlat(t *testing.T){
 	
 	var nlist int
 
+	mt := HAMMING
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 10
-		idx0, err := NewIndexBinFlat(
+		idx0, err := NewIndexBinFlat(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -71,14 +77,14 @@ func TestIndexBinFlat(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexBinFlat(
+		idx0, err := NewIndexBinFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexBinFlat(
+		idx1, err := NewIndexBinFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -91,10 +97,13 @@ func TestIndexIvfFlat(t *testing.T){
 	
 	var nlist int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 10
-		idx0, err := NewIndexIvfFlat(
+		idx0, err := NewIndexIvfFlat(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -109,14 +118,14 @@ func TestIndexIvfFlat(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexIvfFlat(
+		idx0, err := NewIndexIvfFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexIvfFlat(
+		idx1, err := NewIndexIvfFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -129,10 +138,13 @@ func TestIndexBinIvfFlat(t *testing.T){
 	
 	var nlist int
 
+	mt := HAMMING
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 10
-		idx0, err := NewIndexBinIvfFlat(
+		idx0, err := NewIndexBinIvfFlat(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -147,14 +159,14 @@ func TestIndexBinIvfFlat(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexBinIvfFlat(
+		idx0, err := NewIndexBinIvfFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexBinIvfFlat(
+		idx1, err := NewIndexBinIvfFlat(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -167,10 +179,13 @@ func TestIndexIvfSQ8(t *testing.T){
 	
 	var nlist int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 10
-		idx0, err := NewIndexIvfSQ8(
+		idx0, err := NewIndexIvfSQ8(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -185,14 +200,14 @@ func TestIndexIvfSQ8(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexIvfSQ8(
+		idx0, err := NewIndexIvfSQ8(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexIvfSQ8(
+		idx1, err := NewIndexIvfSQ8(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -205,10 +220,13 @@ func TestIndexIvfSQ8H(t *testing.T){
 	
 	var nlist int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist = 10
-		idx0, err := NewIndexIvfSQ8H(
+		idx0, err := NewIndexIvfSQ8H(mt, 
 			nlist,
 		)
 		assert.Nil(t, err)
@@ -223,14 +241,14 @@ func TestIndexIvfSQ8H(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist = 0
-		idx0, err := NewIndexIvfSQ8H(
+		idx0, err := NewIndexIvfSQ8H(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		nlist = 65537
-		idx1, err := NewIndexIvfSQ8H(
+		idx1, err := NewIndexIvfSQ8H(mt, 
 			nlist,
 		)
 		assert.NotNil(t, err)
@@ -245,10 +263,13 @@ func TestIndexIvfPQ(t *testing.T){
 	var m int
 	var nbits int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist, m, nbits = 10, 8, 8
-		idx0, err := NewIndexIvfPQ(
+		idx0, err := NewIndexIvfPQ(mt, 
 			nlist,
 			m,
 			nbits,
@@ -265,7 +286,7 @@ func TestIndexIvfPQ(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist, m, nbits = 0, 8, 8
-		idx0, err := NewIndexIvfPQ(
+		idx0, err := NewIndexIvfPQ(mt, 
 			nlist,
 			m,
 			nbits,
@@ -274,7 +295,7 @@ func TestIndexIvfPQ(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		nlist, m, nbits = 65537, 8, 8
-		idx1, err := NewIndexIvfPQ(
+		idx1, err := NewIndexIvfPQ(mt, 
 			nlist,
 			m,
 			nbits,
@@ -283,7 +304,7 @@ func TestIndexIvfPQ(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		nlist, m, nbits = 10, 8, 0
-		idx2, err := NewIndexIvfPQ(
+		idx2, err := NewIndexIvfPQ(mt, 
 			nlist,
 			m,
 			nbits,
@@ -292,7 +313,7 @@ func TestIndexIvfPQ(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		nlist, m, nbits = 10, 8, 17
-		idx3, err := NewIndexIvfPQ(
+		idx3, err := NewIndexIvfPQ(mt, 
 			nlist,
 			m,
 			nbits,
@@ -310,10 +331,13 @@ func TestIndexRNSG(t *testing.T){
 	var search_length int
 	var knng int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 300, 60, 50
-		idx0, err := NewIndexRNSG(
+		idx0, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -331,7 +355,7 @@ func TestIndexRNSG(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		out_degree, candidate_pool_size, search_length, knng = 4, 300, 60, 50
-		idx0, err := NewIndexRNSG(
+		idx0, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -341,7 +365,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		out_degree, candidate_pool_size, search_length, knng = 301, 300, 60, 50
-		idx1, err := NewIndexRNSG(
+		idx1, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -351,7 +375,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 49, 60, 50
-		idx2, err := NewIndexRNSG(
+		idx2, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -361,7 +385,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 1001, 60, 50
-		idx3, err := NewIndexRNSG(
+		idx3, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -371,7 +395,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx3)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 300, 9, 50
-		idx4, err := NewIndexRNSG(
+		idx4, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -381,7 +405,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx4)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 300, 301, 50
-		idx5, err := NewIndexRNSG(
+		idx5, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -391,7 +415,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx5)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 300, 60, 4
-		idx6, err := NewIndexRNSG(
+		idx6, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -401,7 +425,7 @@ func TestIndexRNSG(t *testing.T){
 		assert.Nil(t, idx6)
 		
 		out_degree, candidate_pool_size, search_length, knng = 30, 300, 60, 301
-		idx7, err := NewIndexRNSG(
+		idx7, err := NewIndexRNSG(mt, 
 			out_degree,
 			candidate_pool_size,
 			search_length,
@@ -418,10 +442,13 @@ func TestIndexHNSW(t *testing.T){
 	var M int
 	var efConstruction int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		M, efConstruction = 16, 40
-		idx0, err := NewIndexHNSW(
+		idx0, err := NewIndexHNSW(mt, 
 			M,
 			efConstruction,
 		)
@@ -437,7 +464,7 @@ func TestIndexHNSW(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		M, efConstruction = 3, 40
-		idx0, err := NewIndexHNSW(
+		idx0, err := NewIndexHNSW(mt, 
 			M,
 			efConstruction,
 		)
@@ -445,7 +472,7 @@ func TestIndexHNSW(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		M, efConstruction = 65, 40
-		idx1, err := NewIndexHNSW(
+		idx1, err := NewIndexHNSW(mt, 
 			M,
 			efConstruction,
 		)
@@ -453,7 +480,7 @@ func TestIndexHNSW(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		M, efConstruction = 16, 7
-		idx2, err := NewIndexHNSW(
+		idx2, err := NewIndexHNSW(mt, 
 			M,
 			efConstruction,
 		)
@@ -461,7 +488,7 @@ func TestIndexHNSW(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		M, efConstruction = 16, 513
-		idx3, err := NewIndexHNSW(
+		idx3, err := NewIndexHNSW(mt, 
 			M,
 			efConstruction,
 		)
@@ -476,10 +503,13 @@ func TestIndexRHNSWFlat(t *testing.T){
 	var M int
 	var efConstruction int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		M, efConstruction = 16, 40
-		idx0, err := NewIndexRHNSWFlat(
+		idx0, err := NewIndexRHNSWFlat(mt, 
 			M,
 			efConstruction,
 		)
@@ -495,7 +525,7 @@ func TestIndexRHNSWFlat(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		M, efConstruction = 3, 40
-		idx0, err := NewIndexRHNSWFlat(
+		idx0, err := NewIndexRHNSWFlat(mt, 
 			M,
 			efConstruction,
 		)
@@ -503,7 +533,7 @@ func TestIndexRHNSWFlat(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		M, efConstruction = 65, 40
-		idx1, err := NewIndexRHNSWFlat(
+		idx1, err := NewIndexRHNSWFlat(mt, 
 			M,
 			efConstruction,
 		)
@@ -511,7 +541,7 @@ func TestIndexRHNSWFlat(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		M, efConstruction = 16, 7
-		idx2, err := NewIndexRHNSWFlat(
+		idx2, err := NewIndexRHNSWFlat(mt, 
 			M,
 			efConstruction,
 		)
@@ -519,7 +549,7 @@ func TestIndexRHNSWFlat(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		M, efConstruction = 16, 513
-		idx3, err := NewIndexRHNSWFlat(
+		idx3, err := NewIndexRHNSWFlat(mt, 
 			M,
 			efConstruction,
 		)
@@ -535,10 +565,13 @@ func TestIndexRHNSW_PQ(t *testing.T){
 	var efConstruction int
 	var PQM int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		M, efConstruction, PQM = 17, 40, 8
-		idx0, err := NewIndexRHNSW_PQ(
+		idx0, err := NewIndexRHNSW_PQ(mt, 
 			M,
 			efConstruction,
 			PQM,
@@ -555,7 +588,7 @@ func TestIndexRHNSW_PQ(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		M, efConstruction, PQM = 3, 40, 8
-		idx0, err := NewIndexRHNSW_PQ(
+		idx0, err := NewIndexRHNSW_PQ(mt, 
 			M,
 			efConstruction,
 			PQM,
@@ -564,7 +597,7 @@ func TestIndexRHNSW_PQ(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		M, efConstruction, PQM = 65, 40, 8
-		idx1, err := NewIndexRHNSW_PQ(
+		idx1, err := NewIndexRHNSW_PQ(mt, 
 			M,
 			efConstruction,
 			PQM,
@@ -573,7 +606,7 @@ func TestIndexRHNSW_PQ(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		M, efConstruction, PQM = 16, 7, 8
-		idx2, err := NewIndexRHNSW_PQ(
+		idx2, err := NewIndexRHNSW_PQ(mt, 
 			M,
 			efConstruction,
 			PQM,
@@ -582,7 +615,7 @@ func TestIndexRHNSW_PQ(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		M, efConstruction, PQM = 16, 513, 8
-		idx3, err := NewIndexRHNSW_PQ(
+		idx3, err := NewIndexRHNSW_PQ(mt, 
 			M,
 			efConstruction,
 			PQM,
@@ -598,10 +631,13 @@ func TestIndexRHNSW_SQ(t *testing.T){
 	var M int
 	var efConstruction int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		M, efConstruction = 16, 40
-		idx0, err := NewIndexRHNSW_SQ(
+		idx0, err := NewIndexRHNSW_SQ(mt, 
 			M,
 			efConstruction,
 		)
@@ -617,7 +653,7 @@ func TestIndexRHNSW_SQ(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		M, efConstruction = 3, 40
-		idx0, err := NewIndexRHNSW_SQ(
+		idx0, err := NewIndexRHNSW_SQ(mt, 
 			M,
 			efConstruction,
 		)
@@ -625,7 +661,7 @@ func TestIndexRHNSW_SQ(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		M, efConstruction = 65, 40
-		idx1, err := NewIndexRHNSW_SQ(
+		idx1, err := NewIndexRHNSW_SQ(mt, 
 			M,
 			efConstruction,
 		)
@@ -633,7 +669,7 @@ func TestIndexRHNSW_SQ(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		M, efConstruction = 16, 7
-		idx2, err := NewIndexRHNSW_SQ(
+		idx2, err := NewIndexRHNSW_SQ(mt, 
 			M,
 			efConstruction,
 		)
@@ -641,7 +677,7 @@ func TestIndexRHNSW_SQ(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		M, efConstruction = 16, 513
-		idx3, err := NewIndexRHNSW_SQ(
+		idx3, err := NewIndexRHNSW_SQ(mt, 
 			M,
 			efConstruction,
 		)
@@ -657,10 +693,13 @@ func TestIndexIvfHNSW(t *testing.T){
 	var M int
 	var efConstruction int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		nlist, M, efConstruction = 10, 16, 40
-		idx0, err := NewIndexIvfHNSW(
+		idx0, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -677,7 +716,7 @@ func TestIndexIvfHNSW(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		nlist, M, efConstruction = 0, 16, 40
-		idx0, err := NewIndexIvfHNSW(
+		idx0, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -686,7 +725,7 @@ func TestIndexIvfHNSW(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		nlist, M, efConstruction = 65537, 16, 40
-		idx1, err := NewIndexIvfHNSW(
+		idx1, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -695,7 +734,7 @@ func TestIndexIvfHNSW(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		nlist, M, efConstruction = 10, 3, 40
-		idx2, err := NewIndexIvfHNSW(
+		idx2, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -704,7 +743,7 @@ func TestIndexIvfHNSW(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		nlist, M, efConstruction = 10, 65, 40
-		idx3, err := NewIndexIvfHNSW(
+		idx3, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -713,7 +752,7 @@ func TestIndexIvfHNSW(t *testing.T){
 		assert.Nil(t, idx3)
 		
 		nlist, M, efConstruction = 10, 16, 7
-		idx4, err := NewIndexIvfHNSW(
+		idx4, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -722,7 +761,7 @@ func TestIndexIvfHNSW(t *testing.T){
 		assert.Nil(t, idx4)
 		
 		nlist, M, efConstruction = 10, 16, 513
-		idx5, err := NewIndexIvfHNSW(
+		idx5, err := NewIndexIvfHNSW(mt, 
 			nlist,
 			M,
 			efConstruction,
@@ -737,10 +776,13 @@ func TestIndexANNOY(t *testing.T){
 	
 	var n_trees int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		n_trees = 8
-		idx0, err := NewIndexANNOY(
+		idx0, err := NewIndexANNOY(mt, 
 			n_trees,
 		)
 		assert.Nil(t, err)
@@ -755,14 +797,14 @@ func TestIndexANNOY(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		n_trees = 0
-		idx0, err := NewIndexANNOY(
+		idx0, err := NewIndexANNOY(mt, 
 			n_trees,
 		)
 		assert.NotNil(t, err)
 		assert.Nil(t, idx0)
 		
 		n_trees = 1025
-		idx1, err := NewIndexANNOY(
+		idx1, err := NewIndexANNOY(mt, 
 			n_trees,
 		)
 		assert.NotNil(t, err)
@@ -777,10 +819,13 @@ func TestIndexNGTPANNG(t *testing.T){
 	var forcedly_pruned_edge_size int
 	var selectively_pruned_edge_size int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 20, 40, 10
-		idx0, err := NewIndexNGTPANNG(
+		idx0, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -797,7 +842,7 @@ func TestIndexNGTPANNG(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 0, 40, 10
-		idx0, err := NewIndexNGTPANNG(
+		idx0, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -806,7 +851,7 @@ func TestIndexNGTPANNG(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 201, 40, 10
-		idx1, err := NewIndexNGTPANNG(
+		idx1, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -815,7 +860,7 @@ func TestIndexNGTPANNG(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 20, 10, 10
-		idx2, err := NewIndexNGTPANNG(
+		idx2, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -824,7 +869,7 @@ func TestIndexNGTPANNG(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 20, 201, 10
-		idx3, err := NewIndexNGTPANNG(
+		idx3, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -833,7 +878,7 @@ func TestIndexNGTPANNG(t *testing.T){
 		assert.Nil(t, idx3)
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 20, 40, 40
-		idx4, err := NewIndexNGTPANNG(
+		idx4, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -842,7 +887,7 @@ func TestIndexNGTPANNG(t *testing.T){
 		assert.Nil(t, idx4)
 		
 		edge_size, forcedly_pruned_edge_size, selectively_pruned_edge_size = 20, 40, 201
-		idx5, err := NewIndexNGTPANNG(
+		idx5, err := NewIndexNGTPANNG(mt, 
 			edge_size,
 			forcedly_pruned_edge_size,
 			selectively_pruned_edge_size,
@@ -859,10 +904,13 @@ func TestIndexNGTONNG(t *testing.T){
 	var outgoing_edge_size int
 	var incoming_edge_size int
 
+	mt := L2
+	
+
 	t.Run("valid usage case", func(t *testing.T){
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 20, 10, 40
-		idx0, err := NewIndexNGTONNG(
+		idx0, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -879,7 +927,7 @@ func TestIndexNGTONNG(t *testing.T){
 	t.Run("invalid usage case", func(t *testing.T){
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 0, 10, 40
-		idx0, err := NewIndexNGTONNG(
+		idx0, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -888,7 +936,7 @@ func TestIndexNGTONNG(t *testing.T){
 		assert.Nil(t, idx0)
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 201, 10, 40
-		idx1, err := NewIndexNGTONNG(
+		idx1, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -897,7 +945,7 @@ func TestIndexNGTONNG(t *testing.T){
 		assert.Nil(t, idx1)
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 20, 0, 40
-		idx2, err := NewIndexNGTONNG(
+		idx2, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -906,7 +954,7 @@ func TestIndexNGTONNG(t *testing.T){
 		assert.Nil(t, idx2)
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 20, 201, 40
-		idx3, err := NewIndexNGTONNG(
+		idx3, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -915,7 +963,7 @@ func TestIndexNGTONNG(t *testing.T){
 		assert.Nil(t, idx3)
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 20, 10, 0
-		idx4, err := NewIndexNGTONNG(
+		idx4, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
@@ -924,7 +972,7 @@ func TestIndexNGTONNG(t *testing.T){
 		assert.Nil(t, idx4)
 		
 		edge_size, outgoing_edge_size, incoming_edge_size = 20, 10, 201
-		idx5, err := NewIndexNGTONNG(
+		idx5, err := NewIndexNGTONNG(mt, 
 			edge_size,
 			outgoing_edge_size,
 			incoming_edge_size,
diff --git a/entity/indexes_search_param_gen_test.go b/entity/indexes_search_param_gen_test.go
index 209da68..6be8231 100755
--- a/entity/indexes_search_param_gen_test.go
+++ b/entity/indexes_search_param_gen_test.go
@@ -1,5 +1,5 @@
 // Code generated by go generate; DO NOT EDIT
-// This file is generated by go generate at 2021-07-15 10:38:56.086006767 +0800 CST m=+0.005470307
+// This file is generated by go generate at 2021-07-15 12:08:49.007744289 +0800 CST m=+0.005951592
 
 //Package entity defineds entities used in sdk
 package entity