diff --git a/CHANGELOG.md b/CHANGELOG.md index f4c2f74..9f5f371 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## v1.5.0 +* support binary vector +* support query count, and delete with limit +* add params TerminateAfter and CutoffFrequency, when hybrid search +* support modify vector indexes + ## v1.4.9 * 为tcvectordb包的部分接口,增加注释 * ExistsDatabase实现方法中:增加对AI_DB类型数据库的判断 diff --git a/example/binary_demo/main.go b/example/binary_demo/main.go new file mode 100644 index 0000000..8a75a73 --- /dev/null +++ b/example/binary_demo/main.go @@ -0,0 +1,312 @@ +package main + +import ( + "context" + "errors" + "fmt" + "log" + "time" + + "github.com/tencent/vectordatabase-sdk-go/tcvectordb" + "github.com/tencent/vectordatabase-sdk-go/tcvectordb/utils" +) + +type Demo struct { + //client *tcvectordb.Client + client *tcvectordb.RpcClient +} + +func NewDemo(url, username, key string) (*Demo, error) { + // cli, err := tcvectordb.NewClient(url, username, key, &tcvectordb.ClientOption{ + // ReadConsistency: tcvectordb.EventualConsistency}) + cli, err := tcvectordb.NewRpcClient(url, username, key, &tcvectordb.ClientOption{ + ReadConsistency: tcvectordb.StrongConsistency}) + if err != nil { + return nil, err + } + // disable/enable http request log print + // cli.Debug(false) + return &Demo{client: cli}, nil +} + +func (d *Demo) Clear(ctx context.Context, database string) error { + log.Println("--------------------------- DropDatabase ---------------------------") + result, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", result) + return nil +} + +func (d *Demo) DeleteAndDrop(ctx context.Context, database, collection string) error { + // 删除collection,删除collection的同时,其中的数据也将被全部删除 + log.Println("-------------------------- DropCollection --------------------------") + colDropResult, err := d.client.Database(database).DropCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("drop collection result: %+v", colDropResult) + + log.Println("--------------------------- DropDatabase ---------------------------") + // 删除db,db下的所有collection都将被删除 + dbDropResult, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", dbDropResult) + return nil +} + +func (d *Demo) CreateDBAndCollection(ctx context.Context, database, collection, alias string) error { + // 创建DB--'book' + log.Println("-------------------------- CreateDatabase --------------------------") + db, err := d.client.CreateDatabase(ctx, database) + if err != nil { + return err + } + + log.Println("--------------------------- ListDatabase ---------------------------") + dbList, err := d.client.ListDatabase(ctx) + if err != nil { + return err + } + for _, db := range dbList.Databases { + log.Printf("database: %s", db.DatabaseName) + } + + log.Println("------------------------- CreateCollection -------------------------") + index := tcvectordb.Indexes{} + index.VectorIndex = append(index.VectorIndex, tcvectordb.VectorIndex{ + FilterIndex: tcvectordb.FilterIndex{ + FieldName: "vector", + FieldType: tcvectordb.BinaryVector, + IndexType: tcvectordb.BIN_FLAT, + }, + Dimension: 16, + MetricType: tcvectordb.HAMMING, + }) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "id", FieldType: tcvectordb.String, IndexType: tcvectordb.PRIMARY}) + + maxStrLen := uint32(32) + param := &tcvectordb.CreateCollectionParams{ + FilterIndexConfig: &tcvectordb.FilterIndexConfig{ + FilterAll: true, + FieldsWithoutIndex: []string{"bookName"}, + MaxStrLen: &maxStrLen, + }, + } + + db.WithTimeout(time.Second * 30) + _, err = db.CreateCollection(ctx, collection, 3, 1, "test collection", index, param) + if err != nil { + return err + } + + log.Println("-------------------------- ListCollection --------------------------") + // 列出所有 Collection + collListRes, err := db.ListCollection(ctx) + if err != nil { + return err + } + for _, col := range collListRes.Collections { + log.Printf("ListCollection: %+v", col) + } + + log.Println("----------------------------- SetAlias -----------------------------") + // 设置 Collection 的 alias + _, err = db.SetAlias(ctx, collection, alias) + if err != nil { + return err + } + + log.Println("------------------------ DescribeCollection ------------------------") + // 查看 Collection 信息 + colRes, err := db.DescribeCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("DescribeCollection: %+v", colRes) + + log.Println("---------------------------- DeleteAlias ---------------------------") + // 删除 Collection 的 alias + delAliasRes, err := db.DeleteAlias(ctx, alias) + if err != nil { + return err + } + log.Printf("DeleteAliasResult: %v", delAliasRes) + return nil +} + +func (d *Demo) UpsertData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Upsert ------------------------------") + + binaryVectors := [][]byte{ + {1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1}, + } + + insertVectors := make([][]float32, 0) + for i, binaryVector := range binaryVectors { + res, err := utils.BinaryToUint8(binaryVector) + if err != nil { + return errors.New(fmt.Sprintf("convert i: %v, err: %v", i, err)) + } + insertVectors = append(insertVectors, res) + } + documentList := []tcvectordb.Document{ + { + Id: "0001", + Vector: insertVectors[0], + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 21}, + "segment": {Val: "富贵功名,前缘分定,为人切莫欺心。"}, + }, + }, + { + Id: "0002", + Vector: insertVectors[1], + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 22}, + "segment": {Val: "正大光明,忠良善果弥深。些些狂妄天加谴,眼前不遇待时临。"}, + }, + }, + { + Id: "0003", + Vector: insertVectors[2], + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 23}, + "segment": {Val: "细作探知这个消息,飞报吕布。"}, + }, + }, + { + Id: "0004", + Vector: insertVectors[3], + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 24}, + "segment": {Val: "布大惊,与陈宫商议。宫曰:“闻刘玄德新领徐州,可往投之。”布从其言,竟投徐州来。有人报知玄德。"}, + }, + }, + { + Id: "0005", + Vector: insertVectors[4], + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 25}, + "segment": {Val: "玄德曰:“布乃当今英勇之士,可出迎之。”糜竺曰:“吕布乃虎狼之徒,不可收留;收则伤人矣。"}, + }, + }, + } + result, err := coll.Upsert(ctx, documentList) + if err != nil { + return err + } + log.Printf("UpsertResult: %+v", result) + return nil +} + +func (d *Demo) QueryAndSearchData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Query ------------------------------") + documentIds := []string{"0001", "0002", "0003", "0004", "0005"} + filter := tcvectordb.NewFilter(`bookName="三国演义"`) + outputField := []string{"id", "bookName"} + + result, err := coll.Query(ctx, documentIds, &tcvectordb.QueryDocumentParams{ + Filter: filter, + RetrieveVector: false, + OutputFields: outputField, + Limit: 2, + Offset: 1, + }) + if err != nil { + return err + } + log.Printf("QueryResult: total: %v, affect: %v", result.Total, result.AffectedCount) + for _, doc := range result.Documents { + log.Printf("QueryDocument: %+v", doc) + } + + log.Println("------------------------------ Query ------------------------------") + + filter = tcvectordb.NewFilter(`author="吴承恩"`) + _, err = coll.Query(ctx, documentIds, &tcvectordb.QueryDocumentParams{ + Filter: filter, + RetrieveVector: false, + OutputFields: outputField, + Limit: 2, + Offset: 1, + }) + if err == nil { + log.Printf("query succ. Because the author filter" + + " will be ignored, when filterAll is true ") + } + + log.Println("------------------------------ Search ------------------------------") + + searchVector, err := utils.BinaryToUint8([]byte{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1}) + if err != nil { + return fmt.Errorf("convert failed, err: %v", err.Error()) + } + + searchResult, err := coll.Search(ctx, + [][]float32{searchVector}, //指定检索向量,最多指定20个 + &tcvectordb.SearchDocumentParams{ + RetrieveVector: true, + Limit: 2, + }) + if err != nil { + return err + } + // 输出相似性检索结果,检索结果为二维数组,每一位为一组返回结果,分别对应search时指定的多个向量 + for i, item := range searchResult.Documents { + log.Printf("SearchDocumentResult, index: %d ==================", i) + for _, doc := range item { + log.Printf("SearchDocument: %+v", doc) + } + } + return nil +} + +func printErr(err error) { + if err != nil { + log.Fatal(err) + } +} + +func main() { + database := "go-sdk-demo-db" + collectionName := "go-sdk-demo-col" + collectionAlias := "go-sdk-demo-alias" + + ctx := context.Background() + testVdb, err := NewDemo("vdb http url or ip and port", "vdb username", "key get from web console") + printErr(err) + err = testVdb.Clear(ctx, database) + printErr(err) + err = testVdb.CreateDBAndCollection(ctx, database, collectionName, collectionAlias) + printErr(err) + err = testVdb.UpsertData(ctx, database, collectionName) + printErr(err) + err = testVdb.QueryAndSearchData(ctx, database, collectionName) + printErr(err) + err = testVdb.DeleteAndDrop(ctx, database, collectionName) + printErr(err) +} diff --git a/example/count_and_delete_limit_demo/main.go b/example/count_and_delete_limit_demo/main.go new file mode 100644 index 0000000..e6d807a --- /dev/null +++ b/example/count_and_delete_limit_demo/main.go @@ -0,0 +1,286 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/tencent/vectordatabase-sdk-go/tcvectordb" +) + +type Demo struct { + client *tcvectordb.Client + //client *tcvectordb.RpcClient +} + +func NewDemo(url, username, key string) (*Demo, error) { + cli, err := tcvectordb.NewClient(url, username, key, &tcvectordb.ClientOption{ + ReadConsistency: tcvectordb.EventualConsistency}) + // cli, err := tcvectordb.NewRpcClient(url, username, key, &tcvectordb.ClientOption{ + // ReadConsistency: tcvectordb.EventualConsistency}) + if err != nil { + return nil, err + } + // disable/enable http request log print + // cli.Debug(false) + return &Demo{client: cli}, nil +} + +func (d *Demo) Clear(ctx context.Context, database string) error { + log.Println("--------------------------- DropDatabase ---------------------------") + result, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", result) + return nil +} + +func (d *Demo) DeleteAndDrop(ctx context.Context, database, collection string) error { + // 删除collection,删除collection的同时,其中的数据也将被全部删除 + log.Println("-------------------------- DropCollection --------------------------") + colDropResult, err := d.client.Database(database).DropCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("drop collection result: %+v", colDropResult) + + log.Println("--------------------------- DropDatabase ---------------------------") + // 删除db,db下的所有collection都将被删除 + dbDropResult, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", dbDropResult) + return nil +} + +func (d *Demo) CreateDBAndCollection(ctx context.Context, database, collection, alias string) error { + // 创建DB--'book' + log.Println("-------------------------- CreateDatabase --------------------------") + db, err := d.client.CreateDatabase(ctx, database) + if err != nil { + return err + } + + log.Println("--------------------------- ListDatabase ---------------------------") + dbList, err := d.client.ListDatabase(ctx) + if err != nil { + return err + } + for _, db := range dbList.Databases { + log.Printf("database: %s", db.DatabaseName) + } + + log.Println("------------------------- CreateCollection -------------------------") + // 创建 Collection + + // 第一步,设计索引(不是设计 Collection 的结构) + // 1. 【重要的事】向量对应的文本字段不要建立索引,会浪费较大的内存,并且没有任何作用。 + // 2. 【必须的索引】:主键id、向量字段 vector 这两个字段目前是固定且必须的,参考下面的例子; + // 3. 【其他索引】:检索时需作为条件查询的字段,比如要按书籍的作者进行过滤,这个时候 author 字段就需要建立索引, + // 否则无法在查询的时候对 author 字段进行过滤,不需要过滤的字段无需加索引,会浪费内存; + // 4. 向量数据库支持动态 Schema,写入数据时可以写入任何字段,无需提前定义,类似 MongoDB. + // 5. 例子中创建一个书籍片段的索引,例如书籍片段的信息包括 {id, vector, segment, bookName, author, page}, + // id 为主键需要全局唯一,segment 为文本片段, vector 字段需要建立向量索引,假如我们在查询的时候要查询指定书籍 + // 名称的内容,这个时候需要对 bookName 建立索引,其他字段没有条件查询的需要,无需建立索引。 + index := tcvectordb.Indexes{} + index.VectorIndex = append(index.VectorIndex, tcvectordb.VectorIndex{ + FilterIndex: tcvectordb.FilterIndex{ + FieldName: "vector", + FieldType: tcvectordb.Vector, + IndexType: tcvectordb.HNSW, + }, + Dimension: 3, + MetricType: tcvectordb.COSINE, + Params: &tcvectordb.HNSWParam{ + M: 16, + EfConstruction: 200, + }, + }) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "id", FieldType: tcvectordb.String, IndexType: tcvectordb.PRIMARY}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "bookName", FieldType: tcvectordb.String, IndexType: tcvectordb.FILTER}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "page", FieldType: tcvectordb.Uint64, IndexType: tcvectordb.FILTER}) + + // 第二步:创建 Collection + // 创建collection耗时较长,需要调整客户端的timeout + // 这里以三可用区实例作为参考,具体实例不同的规格所支持的shard和replicas区间不同,需要参考官方文档 + db.WithTimeout(time.Second * 30) + _, err = db.CreateCollection(ctx, collection, 3, 1, "test collection", index) + if err != nil { + return err + } + + log.Println("-------------------------- ListCollection --------------------------") + // 列出所有 Collection + collListRes, err := db.ListCollection(ctx) + if err != nil { + return err + } + for _, col := range collListRes.Collections { + log.Printf("ListCollection: %+v", col) + } + + log.Println("----------------------------- SetAlias -----------------------------") + // 设置 Collection 的 alias + _, err = db.SetAlias(ctx, collection, alias) + if err != nil { + return err + } + + log.Println("------------------------ DescribeCollection ------------------------") + // 查看 Collection 信息 + colRes, err := db.DescribeCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("DescribeCollection: %+v", colRes) + + log.Println("---------------------------- DeleteAlias ---------------------------") + // 删除 Collection 的 alias + delAliasRes, err := db.DeleteAlias(ctx, alias) + if err != nil { + return err + } + log.Printf("DeleteAliasResult: %v", delAliasRes) + return nil +} + +func (d *Demo) UpsertData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Upsert ------------------------------") + // upsert 写入数据,可能会有一定延迟 + // 1. 支持动态 Schema,除了 id、vector 字段必须写入,可以写入其他任意字段; + // 2. upsert 会执行覆盖写,若文档id已存在,则新数据会直接覆盖原有数据(删除原有数据,再插入新数据) + + documentList := []tcvectordb.Document{ + { + Id: "0001", + Vector: []float32{0.2123, 0.21, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 21}, + "segment": {Val: "富贵功名,前缘分定,为人切莫欺心。"}, + }, + }, + { + Id: "0002", + Vector: []float32{0.2123, 0.22, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 22}, + "segment": {Val: "正大光明,忠良善果弥深。些些狂妄天加谴,眼前不遇待时临。"}, + }, + }, + { + Id: "0003", + Vector: []float32{0.2123, 0.23, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 23}, + "segment": {Val: "细作探知这个消息,飞报吕布。"}, + }, + }, + { + Id: "0004", + Vector: []float32{0.2123, 0.24, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 24}, + "segment": {Val: "布大惊,与陈宫商议。宫曰:“闻刘玄德新领徐州,可往投之。”布从其言,竟投徐州来。有人报知玄德。"}, + }, + }, + { + Id: "0005", + Vector: []float32{0.2123, 0.25, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 25}, + "segment": {Val: "玄德曰:“布乃当今英勇之士,可出迎之。”糜竺曰:“吕布乃虎狼之徒,不可收留;收则伤人矣。"}, + }, + }, + } + result, err := coll.Upsert(ctx, documentList) + if err != nil { + return err + } + log.Printf("UpsertResult: %+v", result) + return nil +} + +func (d *Demo) CountAndDeleteLimitData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Count with no filter------------------------------") + result, err := coll.Count(ctx) + if err != nil { + return err + } + log.Printf("CountResult with no filter, count: %v", result.Count) + + log.Println("------------------------------ Count ------------------------------") + filter := tcvectordb.NewFilter(`bookName="三国演义"`) + + result, err = coll.Count(ctx, tcvectordb.CountDocumentParams{ + CountFilter: filter, + }) + if err != nil { + return err + } + log.Printf("CountResult, filter: %v, count: %v", filter.Cond(), result.Count) + + log.Println("------------------------------ delete with limit ------------------------------") + delResult, err := coll.Delete(ctx, tcvectordb.DeleteDocumentParams{ + Filter: filter, + Limit: 1, + }) + if err != nil { + return err + } + log.Printf("DeleteResult: %+v", delResult) + + log.Println("------------------------------ Count ------------------------------") + result, err = coll.Count(ctx, tcvectordb.CountDocumentParams{ + CountFilter: filter, + }) + if err != nil { + return err + } + log.Printf("CountResult, filter: %v, count: %v", filter.Cond(), result.Count) + + return nil +} + +func printErr(err error) { + if err != nil { + log.Fatal(err) + } +} + +func main() { + database := "go-sdk-demo-db" + collectionName := "go-sdk-demo-col" + collectionAlias := "go-sdk-demo-alias" + + ctx := context.Background() + testVdb, err := NewDemo("vdb http url or ip and port", "vdb username", "key get from web console") + printErr(err) + err = testVdb.Clear(ctx, database) + printErr(err) + err = testVdb.CreateDBAndCollection(ctx, database, collectionName, collectionAlias) + printErr(err) + err = testVdb.UpsertData(ctx, database, collectionName) + printErr(err) + err = testVdb.CountAndDeleteLimitData(ctx, database, collectionName) + printErr(err) + err = testVdb.DeleteAndDrop(ctx, database, collectionName) + printErr(err) +} diff --git a/example/sparse_vector_demo/main.go b/example/hybrid_search_demo/main.go similarity index 100% rename from example/sparse_vector_demo/main.go rename to example/hybrid_search_demo/main.go diff --git a/example/sparse_vector_demo_with_encoder/main.go b/example/hybrid_search_demo_with_text_encoder/main.go similarity index 99% rename from example/sparse_vector_demo_with_encoder/main.go rename to example/hybrid_search_demo_with_text_encoder/main.go index de7f8aa..2fb85bf 100644 --- a/example/sparse_vector_demo_with_encoder/main.go +++ b/example/hybrid_search_demo_with_text_encoder/main.go @@ -274,7 +274,7 @@ func (d *Demo) QueryData(ctx context.Context, database, collection string) error Weight: []float32{0.1, 0.9}, }, Limit: &limit, - OutputFields: []string{"id", "sparse_vector"}, + OutputFields: []string{"id", "sparse_vector", "text"}, }) if err != nil { return err diff --git a/example/hybrid_search_with_embedding/main.go b/example/hybrid_search_with_embedding/main.go new file mode 100644 index 0000000..e06019e --- /dev/null +++ b/example/hybrid_search_with_embedding/main.go @@ -0,0 +1,300 @@ +package main + +import ( + "context" + "log" + "strconv" + "time" + + "github.com/tencent/vectordatabase-sdk-go/tcvdbtext/encoder" + "github.com/tencent/vectordatabase-sdk-go/tcvectordb" +) + +type Demo struct { + //client *tcvectordb.Client + client *tcvectordb.RpcClient + Bm25 encoder.SparseEncoder +} + +func NewDemo(url, username, key string) (*Demo, error) { + cli, err := tcvectordb.NewRpcClient(url, username, key, &tcvectordb.ClientOption{ + ReadConsistency: tcvectordb.EventualConsistency}) + // cli, err := tcvectordb.NewClient(url, username, key, &tcvectordb.ClientOption{ + // ReadConsistency: tcvectordb.EventualConsistency}) + if err != nil { + return nil, err + } + // disable/enable http request log print + // cli.Debug(false) + + bm25, err := encoder.NewBM25Encoder(&encoder.BM25EncoderParams{Bm25Language: "zh"}) + if err != nil { + log.Fatalf(err.Error()) + } + return &Demo{client: cli, + Bm25: bm25}, nil +} + +func (d *Demo) Clear(ctx context.Context, database string) error { + log.Println("--------------------------- DropDatabase ---------------------------") + result, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", result) + return nil +} + +func (d *Demo) DeleteAndDrop(ctx context.Context, database, collection string) error { + // 删除collection,删除collection的同时,其中的数据也将被全部删除 + log.Println("-------------------------- DropCollection --------------------------") + colDropResult, err := d.client.Database(database).DropCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("drop collection result: %+v", colDropResult) + + log.Println("--------------------------- DropDatabase ---------------------------") + // 删除db,db下的所有collection都将被删除 + dbDropResult, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", dbDropResult) + return nil +} + +func (d *Demo) CreateDBAndCollection(ctx context.Context, database, collection, alias string) error { + // 创建DB--'book' + log.Println("-------------------------- CreateDatabase --------------------------") + db, err := d.client.CreateDatabase(ctx, database) + if err != nil { + return err + } + + log.Println("--------------------------- ListDatabase ---------------------------") + dbList, err := d.client.ListDatabase(ctx) + if err != nil { + return err + } + for _, db := range dbList.Databases { + log.Printf("database: %s", db.DatabaseName) + } + + log.Println("------------------------- CreateCollection with Embedding-------------------------") + // 新建 Collection + // 第一步,设计索引(不是设计表格的结构) + // 1. 【重要的事】向量对应的文本字段不要建立索引,会浪费较大的内存,并且没有任何作用。 + // 2. 【必须的索引】:主键 id、向量字段 vector 这两个字段目前是固定且必须的,参考下面的例子; + // 3. 【其他索引】:检索时需作为条件查询的字段,比如要按书籍的作者进行过滤,这个时候author字段就需要建立索引, + // 否则无法在查询的时候对 author 字段进行过滤,不需要过滤的字段无需加索引,会浪费内存; + // 4. 向量数据库支持动态 Schema,写入数据时可以写入任何字段,无需提前定义,类似 MongoDB. + // 5. 例子中创建一个书籍片段的索引,例如书籍片段的信息包括 {id, vector, segment, bookName, page}, + // id 为主键需要全局唯一,segment 为文本片段, vector 为 segment 的向量,vector 字段需要建立向量索引,假如我们在查询的时候要查询指定书籍 + // 名称的内容,这个时候需要对bookName建立索引,其他字段没有条件查询的需要,无需建立索引。 + // 6. 创建带 Embedding 的 collection 需要保证设置的 vector 索引的维度和 Embedding 所用模型生成向量维度一致,模型及维度关系: + // ----------------------------------------------------- + // bge-base-zh | 768 + // bge-large-zh | 1024 + // m3e-base | 768 + // text2vec-large-chinese | 1024 + // e5-large-v2 | 1024 + // multilingual-e5-base | 768 + // ----------------------------------------------------- + index := tcvectordb.Indexes{} + index.VectorIndex = append(index.VectorIndex, tcvectordb.VectorIndex{ + FilterIndex: tcvectordb.FilterIndex{ + FieldName: "vector", + FieldType: tcvectordb.Vector, + IndexType: tcvectordb.HNSW, + }, + Dimension: 768, + MetricType: tcvectordb.COSINE, + Params: &tcvectordb.HNSWParam{ + M: 16, + EfConstruction: 200, + }, + }) + index.SparseVectorIndex = append(index.SparseVectorIndex, tcvectordb.SparseVectorIndex{ + FieldName: "sparse_vector", + FieldType: tcvectordb.SparseVector, + IndexType: tcvectordb.SPARSE_INVERTED, + MetricType: tcvectordb.IP, + }) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "id", FieldType: tcvectordb.String, IndexType: tcvectordb.PRIMARY}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "bookName", FieldType: tcvectordb.String, IndexType: tcvectordb.FILTER}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "page", FieldType: tcvectordb.Uint64, IndexType: tcvectordb.FILTER}) + + ebd := &tcvectordb.Embedding{VectorField: "vector", Field: "text", ModelName: "bge-base-zh"} + + // 第二步:创建 Collection + // 创建支持 Embedding 的 Collection + db.WithTimeout(time.Second * 30) + _, err = db.CreateCollection(ctx, collection, 3, 1, "test collection", index, &tcvectordb.CreateCollectionParams{ + Embedding: ebd, + }) + if err != nil { + return err + } + + log.Println("-------------------------- ListCollection --------------------------") + // 列出所有 Collection + collListRes, err := db.ListCollection(ctx) + if err != nil { + return err + } + for _, col := range collListRes.Collections { + log.Printf("ListCollection: %+v", col) + } + + log.Println("----------------------------- SetAlias -----------------------------") + // 设置 Collection 的 alias + _, err = db.SetAlias(ctx, collection, alias) + if err != nil { + return err + } + + log.Println("------------------------ DescribeCollection ------------------------") + // 查看 Collection 信息 + colRes, err := db.DescribeCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("DescribeCollection: %+v", colRes) + + log.Println("---------------------------- DeleteAlias ---------------------------") + // 删除 Collection 的 alias + delAliasRes, err := db.DeleteAlias(ctx, alias) + if err != nil { + return err + } + log.Printf("DeleteAliasResult: %v", delAliasRes) + return nil +} + +func (d *Demo) UpsertData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Upsert ------------------------------") + // upsert 写入数据,可能会有一定延迟 + // 1. 支持动态 Schema,除了 id、vector 字段必须写入,可以写入其他任意字段; + // 2. upsert 会执行覆盖写,若文档id已存在,则新数据会直接覆盖原有数据(删除原有数据,再插入新数据) + + segments := []string{ + "1. 区域中间区域的普通人期望契约C级和B级灵兽,其中一人刚晋升为七品中期御兽师,略过了E级和D级灵兽蛋区域。 2. 御兽神殿的一男一女隐藏了一颗S级灵兽蛋在C级灵兽蛋中,他们对在这所偏远县城的御兽高中能否出现能契约S级灵兽的天骄表示怀疑。 3. 御兽神殿大祭司预言百年未被认可的S级灵兽蛋将在这所高中找到命定主人。 4. 一名清秀少年在人群中径直走向混在C级灵兽蛋区域中的那颗S级灵兽蛋。", + "腾讯云向量数据库(Tencent Cloud VectorDB)是一款全托管的自研企业级分布式数据库服务,专用于存储、索引、检索、管理由深度神经网络或其他机器学习模型生成的大量多维嵌入向量。", + "作为专门为处理输入向量查询而设计的数据库,它支持多种索引类型和相似度计算方法,单索引支持10亿级向量规模,高达百万级 QPS 及毫秒级查询延迟。", + "不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、NLP 服务、计算机视觉、智能客服等 AI 领域。", + "腾讯云向量数据库(Tencent Cloud VectorDB)作为一种专门存储和检索向量数据的服务提供给用户, 在高性能、高可用、大规模、低成本、简单易用、稳定可靠等方面体现出显著优势。 ", + "腾讯云向量数据库可以和大语言模型 LLM 配合使用。企业的私域数据在经过文本分割、向量化后,可以存储在腾讯云向量数据库中,构建起企业专属的外部知识库,从而在后续的检索任务中,为大模型提供提示信息,辅助大模型生成更加准确的答案。", + } + + // 如需了解分词的情况,可参考下一行代码获取 + // tokens := d.Bm25.GetTokenizer().Tokenize(segments[0]) + // fmt.Println("tokens: ", tokens) + + sparse_vectors, err := d.Bm25.EncodeTexts(segments) + if err != nil { + log.Fatalf(err.Error()) + } + + documentList := make([]tcvectordb.Document, 0) + for i := 0; i < 5; i++ { + id := "000" + strconv.Itoa(i) + documentList = append(documentList, tcvectordb.Document{ + Id: id, + Fields: map[string]tcvectordb.Field{ + "text": {Val: segments[i]}, + }, + SparseVector: sparse_vectors[i], + }) + } + + result, err := coll.Upsert(ctx, documentList) + if err != nil { + return err + } + log.Printf("UpsertResult: %+v", result) + return nil +} + +func (d *Demo) HybridSearchWithEmbedding(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ hybridSearch ------------------------------") + + searchText := "1. 区域中间区域的普通人期望契约C级和B级灵兽,其中一人刚晋升为七品中期御兽师,略过了E级和D级灵兽蛋区域。 2. 御兽神殿的一男一女隐藏了一颗S级灵兽蛋在C级灵兽蛋中,他们对在这所偏远县城的御兽高中能否出现能契约S级灵兽的天骄表示怀疑。 3. 御兽神殿大祭司预言百年未被认可的S级灵兽蛋将在这所高中找到命定主人。 4. 一名清秀少年在人群中径直走向混在C级灵兽蛋区域中的那颗S级灵兽蛋。" + annSearch := &tcvectordb.AnnParam{ + FieldName: "text", + Data: searchText, + } + + sparseVec, err := d.Bm25.EncodeQuery(searchText) + if err != nil { + return err + } + keywordSearch := &tcvectordb.MatchOption{ + FieldName: "sparse_vector", + Data: sparseVec, + TerminateAfter: 1, + CutoffFrequency: 0.9, + } + + limit := 2 + searchRes, err := coll.HybridSearch(ctx, tcvectordb.HybridSearchDocumentParams{ + AnnParams: []*tcvectordb.AnnParam{annSearch}, + Match: []*tcvectordb.MatchOption{keywordSearch}, + // rerank也支持rrf,使用方式见下 + // Rerank: &tcvectordb.RerankOption{ + // Method: tcvectordb.RerankRrf, + // RrfK: 1, + // }, + Rerank: &tcvectordb.RerankOption{ + Method: tcvectordb.RerankWeighted, + FieldList: []string{"vector", "sparse_vector"}, + Weight: []float32{0.1, 0.9}, + }, + Limit: &limit, + OutputFields: []string{"id", "sparse_vector"}, + }) + if err != nil { + return err + } + + // 输出相似性检索结果,检索结果为二维数组,每一位为一组返回结果,分别对应search时指定的多个向量 + for i, item := range searchRes.Documents { + log.Printf("HybridSearchDocumentResult, index: %d ==================", i) + for _, doc := range item { + log.Printf("HybridSearchDocument: %+v", doc) + } + } + return nil +} + +func printErr(err error) { + if err != nil { + log.Fatal(err) + } +} + +func main() { + database := "go-sdk-demo-db" + collectionName := "go-sdk-demo-col-sparsevec" + collectionAlias := "go-sdk-demo-col-sparsevec-alias" + + ctx := context.Background() + testVdb, err := NewDemo("vdb http url or ip and port", "root", "key get from web console") + printErr(err) + err = testVdb.Clear(ctx, database) + printErr(err) + err = testVdb.CreateDBAndCollection(ctx, database, collectionName, collectionAlias) + printErr(err) + err = testVdb.UpsertData(ctx, database, collectionName) + printErr(err) + err = testVdb.HybridSearchWithEmbedding(ctx, database, collectionName) + printErr(err) + err = testVdb.DeleteAndDrop(ctx, database, collectionName) + printErr(err) +} diff --git a/example/modify_vector_index/main.go b/example/modify_vector_index/main.go new file mode 100644 index 0000000..502e504 --- /dev/null +++ b/example/modify_vector_index/main.go @@ -0,0 +1,295 @@ +package main + +import ( + "context" + "log" + "time" + + "github.com/tencent/vectordatabase-sdk-go/tcvectordb" + "github.com/tencent/vectordatabase-sdk-go/tcvectordb/api/index" +) + +type Demo struct { + //client *tcvectordb.Client + client *tcvectordb.RpcClient +} + +func NewDemo(url, username, key string) (*Demo, error) { + // cli, err := tcvectordb.NewClient(url, username, key, &tcvectordb.ClientOption{ + // ReadConsistency: tcvectordb.EventualConsistency}) + cli, err := tcvectordb.NewRpcClient(url, username, key, &tcvectordb.ClientOption{ + ReadConsistency: tcvectordb.StrongConsistency}) + if err != nil { + return nil, err + } + // disable/enable http request log print + // cli.Debug(false) + return &Demo{client: cli}, nil +} + +func (d *Demo) Clear(ctx context.Context, database string) error { + log.Println("--------------------------- DropDatabase ---------------------------") + result, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", result) + return nil +} + +func (d *Demo) DeleteAndDrop(ctx context.Context, database, collection string) error { + // 删除collection,删除collection的同时,其中的数据也将被全部删除 + log.Println("-------------------------- DropCollection --------------------------") + colDropResult, err := d.client.Database(database).DropCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("drop collection result: %+v", colDropResult) + + log.Println("--------------------------- DropDatabase ---------------------------") + // 删除db,db下的所有collection都将被删除 + dbDropResult, err := d.client.DropDatabase(ctx, database) + if err != nil { + return err + } + log.Printf("drop database result: %+v", dbDropResult) + return nil +} + +func (d *Demo) CreateDBAndCollection(ctx context.Context, database, collection, alias string) error { + // 创建DB--'book' + log.Println("-------------------------- CreateDatabase --------------------------") + db, err := d.client.CreateDatabase(ctx, database) + if err != nil { + return err + } + + log.Println("--------------------------- ListDatabase ---------------------------") + dbList, err := d.client.ListDatabase(ctx) + if err != nil { + return err + } + for _, db := range dbList.Databases { + log.Printf("database: %s", db.DatabaseName) + } + + log.Println("------------------------- CreateCollection -------------------------") + // 创建 Collection + + // 第一步,设计索引(不是设计 Collection 的结构) + // 1. 【重要的事】向量对应的文本字段不要建立索引,会浪费较大的内存,并且没有任何作用。 + // 2. 【必须的索引】:主键id、向量字段 vector 这两个字段目前是固定且必须的,参考下面的例子; + // 3. 【其他索引】:检索时需作为条件查询的字段,比如要按书籍的作者进行过滤,这个时候 author 字段就需要建立索引, + // 否则无法在查询的时候对 author 字段进行过滤,不需要过滤的字段无需加索引,会浪费内存; + // 4. 向量数据库支持动态 Schema,写入数据时可以写入任何字段,无需提前定义,类似 MongoDB. + // 5. 例子中创建一个书籍片段的索引,例如书籍片段的信息包括 {id, vector, segment, bookName, author, page}, + // id 为主键需要全局唯一,segment 为文本片段, vector 字段需要建立向量索引,假如我们在查询的时候要查询指定书籍 + // 名称的内容,这个时候需要对 bookName 建立索引,其他字段没有条件查询的需要,无需建立索引。 + index := tcvectordb.Indexes{} + index.VectorIndex = append(index.VectorIndex, tcvectordb.VectorIndex{ + FilterIndex: tcvectordb.FilterIndex{ + FieldName: "vector", + FieldType: tcvectordb.Vector, + IndexType: tcvectordb.HNSW, + }, + Dimension: 3, + MetricType: tcvectordb.IP, + Params: &tcvectordb.HNSWParam{ + M: 16, + EfConstruction: 200, + }, + }) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "id", FieldType: tcvectordb.String, IndexType: tcvectordb.PRIMARY}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "bookName", FieldType: tcvectordb.String, IndexType: tcvectordb.FILTER}) + index.FilterIndex = append(index.FilterIndex, tcvectordb.FilterIndex{FieldName: "page", FieldType: tcvectordb.Uint64, IndexType: tcvectordb.FILTER}) + + // 第二步:创建 Collection + // 创建collection耗时较长,需要调整客户端的timeout + // 这里以三可用区实例作为参考,具体实例不同的规格所支持的shard和replicas区间不同,需要参考官方文档 + db.WithTimeout(time.Second * 30) + _, err = db.CreateCollection(ctx, collection, 3, 1, "test collection", index) + if err != nil { + return err + } + + log.Println("-------------------------- ListCollection --------------------------") + // 列出所有 Collection + collListRes, err := db.ListCollection(ctx) + if err != nil { + return err + } + for _, col := range collListRes.Collections { + log.Printf("ListCollection: %+v", col) + } + + log.Println("----------------------------- SetAlias -----------------------------") + // 设置 Collection 的 alias + _, err = db.SetAlias(ctx, collection, alias) + if err != nil { + return err + } + + log.Println("------------------------ DescribeCollection ------------------------") + // 查看 Collection 信息 + colRes, err := db.DescribeCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("DescribeCollection: %+v", colRes) + log.Printf("DescribeCollection: %+v", colRes.Indexes.VectorIndex[0].Params) + + log.Println("---------------------------- DeleteAlias ---------------------------") + // 删除 Collection 的 alias + delAliasRes, err := db.DeleteAlias(ctx, alias) + if err != nil { + return err + } + log.Printf("DeleteAliasResult: %v", delAliasRes) + return nil +} + +func (d *Demo) UpsertData(ctx context.Context, database, collection string) error { + // 获取 Collection 对象 + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ Upsert ------------------------------") + // upsert 写入数据,可能会有一定延迟 + // 1. 支持动态 Schema,除了 id、vector 字段必须写入,可以写入其他任意字段; + // 2. upsert 会执行覆盖写,若文档id已存在,则新数据会直接覆盖原有数据(删除原有数据,再插入新数据) + + documentList := []tcvectordb.Document{ + { + Id: "0001", + Vector: []float32{0.2123, 0.21, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 21}, + "segment": {Val: "富贵功名,前缘分定,为人切莫欺心。"}, + }, + }, + { + Id: "0002", + Vector: []float32{0.2123, 0.22, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "西游记"}, + "author": {Val: "吴承恩"}, + "page": {Val: 22}, + "segment": {Val: "正大光明,忠良善果弥深。些些狂妄天加谴,眼前不遇待时临。"}, + }, + }, + { + Id: "0003", + Vector: []float32{0.2123, 0.23, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 23}, + "segment": {Val: "细作探知这个消息,飞报吕布。"}, + }, + }, + { + Id: "0004", + Vector: []float32{0.2123, 0.24, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 24}, + "segment": {Val: "布大惊,与陈宫商议。宫曰:“闻刘玄德新领徐州,可往投之。”布从其言,竟投徐州来。有人报知玄德。"}, + }, + }, + { + Id: "0005", + Vector: []float32{0.2123, 0.25, 0.213}, + Fields: map[string]tcvectordb.Field{ + "bookName": {Val: "三国演义"}, + "author": {Val: "罗贯中"}, + "page": {Val: 25}, + "segment": {Val: "玄德曰:“布乃当今英勇之士,可出迎之。”糜竺曰:“吕布乃虎狼之徒,不可收留;收则伤人矣。"}, + }, + }, + } + result, err := coll.Upsert(ctx, documentList) + if err != nil { + return err + } + log.Printf("UpsertResult: %+v", result) + return nil +} + +func (d *Demo) ModifyVectorIndex(ctx context.Context, database, collection string) error { + coll := d.client.Database(database).Collection(collection) + + log.Println("------------------------------ ModifyVectorIndex ------------------------------") + + setThrottle := int32(1) + param := tcvectordb.ModifyVectorIndexParam{ + RebuildRules: &index.RebuildRules{ + Throttle: &setThrottle, + }, + } + param.VectorIndexes = make([]tcvectordb.VectorIndex, 0) + param.VectorIndexes = append(param.VectorIndexes, tcvectordb.VectorIndex{ + FilterIndex: tcvectordb.FilterIndex{ + FieldName: "vector", + FieldType: tcvectordb.Vector, + IndexType: tcvectordb.HNSW, + }, + Dimension: 3, + MetricType: tcvectordb.COSINE, + Params: &tcvectordb.HNSWParam{ + M: 8, + EfConstruction: 0, + }}) + + err := coll.ModifyVectorIndex(ctx, param) + if err != nil { + return err + } + + return nil +} + +func (d *Demo) DescribeCollection(ctx context.Context, database, collection string) error { + db := d.client.Database(database) + log.Println("------------------------ DescribeCollection ------------------------") + // 查看 Collection 信息 + colRes, err := db.DescribeCollection(ctx, collection) + if err != nil { + return err + } + log.Printf("DescribeCollection: %+v", colRes) + log.Printf("DescribeCollection: %+v", colRes.Indexes.VectorIndex[0].Params) + return nil +} + +func printErr(err error) { + if err != nil { + log.Fatal(err) + } +} + +func main() { + database := "go-sdk-demo-db" + collectionName := "go-sdk-demo-col" + collectionAlias := "go-sdk-demo-alias" + + ctx := context.Background() + testVdb, err := NewDemo("vdb http url or ip and port", "vdb username", "key get from web console") + printErr(err) + err = testVdb.Clear(ctx, database) + printErr(err) + err = testVdb.CreateDBAndCollection(ctx, database, collectionName, collectionAlias) + printErr(err) + + err = testVdb.UpsertData(ctx, database, collectionName) + printErr(err) + time.Sleep(2 * time.Second) + err = testVdb.ModifyVectorIndex(ctx, database, collectionName) + printErr(err) + time.Sleep(2 * time.Second) + err = testVdb.DescribeCollection(ctx, database, collectionName) + printErr(err) + err = testVdb.DeleteAndDrop(ctx, database, collectionName) + printErr(err) +} diff --git a/tcvectordb/api/collection/api.go b/tcvectordb/api/collection/api.go index 8d03139..4138886 100644 --- a/tcvectordb/api/collection/api.go +++ b/tcvectordb/api/collection/api.go @@ -22,21 +22,27 @@ import "github.com/tencent/vectordatabase-sdk-go/tcvectordb/api" // CreateReq create collection request type CreateReq struct { - api.Meta `path:"/collection/create" tags:"Collection" method:"Post" summary:"创建collection"` - Database string `json:"database,omitempty"` - Collection string `json:"collection,omitempty"` - ReplicaNum uint32 `json:"replicaNum,omitempty"` - ShardNum uint32 `json:"shardNum,omitempty"` - Size uint64 `json:"size,omitempty"` - CreateTime string `json:"createTime,omitempty"` - Description string `json:"description,omitempty"` - Indexes []*api.IndexColumn `json:"indexes,omitempty"` - IndexStatus *IndexStatus `json:"indexStatus,omitempty"` - AliasList []string `json:"alias_list,omitempty"` - Embedding Embedding `json:"embedding"` - TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` + api.Meta `path:"/collection/create" tags:"Collection" method:"Post" summary:"创建collection"` + Database string `json:"database,omitempty"` + Collection string `json:"collection,omitempty"` + ReplicaNum uint32 `json:"replicaNum,omitempty"` + ShardNum uint32 `json:"shardNum,omitempty"` + Size uint64 `json:"size,omitempty"` + CreateTime string `json:"createTime,omitempty"` + Description string `json:"description,omitempty"` + Indexes []*api.IndexColumn `json:"indexes,omitempty"` + IndexStatus *IndexStatus `json:"indexStatus,omitempty"` + AliasList []string `json:"alias_list,omitempty"` + Embedding Embedding `json:"embedding"` + FilterIndexConfig *FilterIndexConfig `json:"filterIndexConfig,omitempty"` + TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` +} + +type FilterIndexConfig struct { + FilterAll bool `json:"filterAll"` + FieldsWithoutIndex []string `json:"fieldsWithoutIndex,omitempty"` + MaxStrLen *uint32 `json:"maxStrLen,omitempty"` } - type Embedding struct { Field string `json:"field,omitempty"` VectorField string `json:"vectorField,omitempty"` @@ -99,19 +105,20 @@ type ListRes struct { } type DescribeCollectionItem struct { - Database string `json:"database,omitempty"` - Collection string `json:"collection,omitempty"` - ReplicaNum uint32 `json:"replicaNum,omitempty"` - ShardNum uint32 `json:"shardNum,omitempty"` - Size uint64 `json:"size,omitempty"` - CreateTime string `json:"createTime,omitempty"` - Description string `json:"description,omitempty"` - Indexes []*api.IndexColumn `json:"indexes,omitempty"` - IndexStatus *IndexStatus `json:"indexStatus,omitempty"` - Alias []string `json:"alias"` - DocumentCount int64 `json:"documentCount,omitempty"` - Embedding *EmbeddingRes `json:"embedding,omitempty"` - TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` + Database string `json:"database,omitempty"` + Collection string `json:"collection,omitempty"` + ReplicaNum uint32 `json:"replicaNum,omitempty"` + ShardNum uint32 `json:"shardNum,omitempty"` + Size uint64 `json:"size,omitempty"` + CreateTime string `json:"createTime,omitempty"` + Description string `json:"description,omitempty"` + Indexes []*api.IndexColumn `json:"indexes,omitempty"` + IndexStatus *IndexStatus `json:"indexStatus,omitempty"` + Alias []string `json:"alias"` + DocumentCount int64 `json:"documentCount,omitempty"` + Embedding *EmbeddingRes `json:"embedding,omitempty"` + TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` + FilterIndexConfig *FilterIndexConfig `json:"filterIndexConfig,omitempty"` } type TruncateReq struct { diff --git a/tcvectordb/api/document/api.go b/tcvectordb/api/document/api.go index d5e0497..62812ad 100644 --- a/tcvectordb/api/document/api.go +++ b/tcvectordb/api/document/api.go @@ -152,9 +152,11 @@ type RerankOption struct { RrfK int32 `protobuf:"varint,3,opt,name=rrf_k,json=rrfK,proto3" json:"rrf_k,omitempty"` // for RRF: K参数 } type MatchOption struct { - FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName,omitempty"` - Data [][][]interface{} `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - Limit int `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName,omitempty"` + Data [][][]interface{} `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + Limit int `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + TerminateAfter uint32 `json:"terminateAfter,omitempty"` + CutoffFrequency float64 `json:"cutoffFrequency,omitempty"` } type AnnParam struct { @@ -210,6 +212,25 @@ type QueryRes struct { Documents []*Document `json:"documents,omitempty"` } +// CountReq query document request +type CountReq struct { + api.Meta `path:"/document/count" tags:"Document" method:"Post" summary:"基于Filter统计文档数量"` + Database string `json:"database,omitempty"` + Collection string `json:"collection,omitempty"` + Query *CountQueryCond `json:"query,omitempty"` + ReadConsistency string `json:"readConsistency,omitempty"` +} + +type CountQueryCond struct { + Filter string `json:"filter,omitempty"` +} + +// QueryRes query document response +type CountRes struct { + api.CommonRes + Count uint64 `json:"count,omitempty"` +} + // DeleteReq delete document request type DeleteReq struct { api.Meta `path:"/document/delete" tags:"Document" method:"Post" summary:"删除指定id的文档,flat 索引不支持删除"` diff --git a/tcvectordb/api/index/api.go b/tcvectordb/api/index/api.go index 00fd79b..cbe67d7 100644 --- a/tcvectordb/api/index/api.go +++ b/tcvectordb/api/index/api.go @@ -46,3 +46,20 @@ type AddReq struct { type AddRes struct { api.CommonRes } + +type ModifyVectorIndexReq struct { + api.Meta `path:"/index/modifyVectorIndex" tags:"Index" method:"Post" summary:"调整collection的向量索引参数"` + Database string `json:"database,omitempty"` + Collection string `json:"collection,omitempty"` + VectorIndexes []*api.IndexColumn `json:"vectorIndexes,omitempty"` + RebuildRules *RebuildRules `json:"rebuildRules,omitempty"` +} + +type RebuildRules struct { + DropBeforeRebuild *bool `json:"dropBeforeRebuild,omitempty"` + Throttle *int32 `json:"throttle,omitempty"` +} + +type ModifyVectorIndexRes struct { + api.CommonRes +} diff --git a/tcvectordb/base_collection.go b/tcvectordb/base_collection.go index 524273a..45a3f9f 100644 --- a/tcvectordb/base_collection.go +++ b/tcvectordb/base_collection.go @@ -77,8 +77,9 @@ type implementerCollection struct { // In this case, the document will be automatically removed after 60 minites when the time specified // in the expire_at field is reached. type CreateCollectionParams struct { - Embedding *Embedding - TtlConfig *TtlConfig + Embedding *Embedding + TtlConfig *TtlConfig + FilterIndexConfig *FilterIndexConfig } type CreateCollectionResult struct { @@ -218,6 +219,12 @@ func (i *implementerCollection) CreateCollection(ctx context.Context, name strin req.TtlConfig.Enable = param.TtlConfig.Enable req.TtlConfig.TimeField = param.TtlConfig.TimeField } + if param.FilterIndexConfig != nil { + req.FilterIndexConfig = new(collection.FilterIndexConfig) + req.FilterIndexConfig.FilterAll = param.FilterIndexConfig.FilterAll + req.FilterIndexConfig.FieldsWithoutIndex = param.FilterIndexConfig.FieldsWithoutIndex + req.FilterIndexConfig.MaxStrLen = param.FilterIndexConfig.MaxStrLen + } } res := new(collection.CreateRes) @@ -429,6 +436,12 @@ func (i *implementerCollection) toCollection(collectionItem *collection.Describe coll.TtlConfig.Enable = collectionItem.TtlConfig.Enable coll.TtlConfig.TimeField = collectionItem.TtlConfig.TimeField } + if collectionItem.FilterIndexConfig != nil { + coll.FilterIndexConfig = new(FilterIndexConfig) + coll.FilterIndexConfig.FilterAll = collectionItem.FilterIndexConfig.FilterAll + coll.FilterIndexConfig.FieldsWithoutIndex = collectionItem.FilterIndexConfig.FieldsWithoutIndex + coll.FilterIndexConfig.MaxStrLen = collectionItem.FilterIndexConfig.MaxStrLen + } if collectionItem.IndexStatus != nil { coll.IndexStatus = IndexStatus{ @@ -563,19 +576,20 @@ func optionParams(column *api.IndexColumn, v VectorIndex) { type Collection struct { DocumentInterface `json:"-"` IndexInterface `json:"-"` - DatabaseName string `json:"databaseName"` - CollectionName string `json:"collectionName"` - DocumentCount int64 `json:"documentCount"` - Alias []string `json:"alias"` - ShardNum uint32 `json:"shardNum"` - ReplicasNum uint32 `json:"replicasNum"` - Indexes Indexes `json:"indexes"` - IndexStatus IndexStatus `json:"indexStatus"` - Embedding Embedding `json:"embedding"` - Description string `json:"description"` - Size uint64 `json:"size"` - CreateTime time.Time `json:"createTime"` - TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` + DatabaseName string `json:"databaseName"` + CollectionName string `json:"collectionName"` + DocumentCount int64 `json:"documentCount"` + Alias []string `json:"alias"` + ShardNum uint32 `json:"shardNum"` + ReplicasNum uint32 `json:"replicasNum"` + Indexes Indexes `json:"indexes"` + IndexStatus IndexStatus `json:"indexStatus"` + Embedding Embedding `json:"embedding"` + Description string `json:"description"` + Size uint64 `json:"size"` + CreateTime time.Time `json:"createTime"` + TtlConfig *TtlConfig `json:"ttlConfig,omitempty"` + FilterIndexConfig *FilterIndexConfig `json:"filterIndexConfig,omitempty"` } func (c *Collection) Debug(v bool) { @@ -604,3 +618,9 @@ type TtlConfig struct { Enable bool `json:"enable"` TimeField string `json:"timeField,omitempty"` } + +type FilterIndexConfig struct { + FilterAll bool `json:"filterAll"` + FieldsWithoutIndex []string `json:"fieldsWithoutIndex,omitempty"` + MaxStrLen *uint32 `json:"maxStrLen,omitempty"` +} diff --git a/tcvectordb/base_document.go b/tcvectordb/base_document.go index f19f147..695bb12 100644 --- a/tcvectordb/base_document.go +++ b/tcvectordb/base_document.go @@ -59,6 +59,9 @@ type DocumentInterface interface { // [Update] updates documents by conditions. Update(ctx context.Context, param UpdateDocumentParams) (result *UpdateDocumentResult, err error) + + // [Count] counts the number of documents in a collection that satisfy the specified filter conditions. + Count(ctx context.Context, params ...CountDocumentParams) (*CountDocumentResult, error) } type FlatInterface interface { @@ -87,6 +90,10 @@ type FlatInterface interface { // [Update] updates documents by conditions. Update(ctx context.Context, databaseName, collectionName string, param UpdateDocumentParams) (result *UpdateDocumentResult, err error) + + // [Count] counts the number of documents in a collection that satisfy the specified filter conditions. + Count(ctx context.Context, databaseName, collectionName string, + params ...CountDocumentParams) (*CountDocumentResult, error) } type implementerDocument struct { @@ -301,10 +308,17 @@ type RerankOption struct { // - FieldName: The field name for sparse vector retrieval, for example: sparse_vector. // - Data: The sparse vectors to retrieve, supporting only sparse vectors for one sentence. // - Limit: The number of results returned from sparse vector retrieval. +// - TerminateAfter: (Optional) Threshold for early termination of keyword search, +// used to improve search efficiency. +// - CutoffFrequency: (Optional) CutoffFrequency specifies a positive integer limit, ranging from [1, +∞]. +// If the term frequency is less than the cutoffFrequency, the term will be ignored during retrieval. +// It also supports decimal values within the range [0,1]. type MatchOption struct { - FieldName string - Data interface{} - Limit *int + FieldName string + Data interface{} + Limit *int + TerminateAfter uint32 + CutoffFrequency float64 } // [AnnParam] holds the parameters for vectors hybrid retrieval configuration. @@ -342,9 +356,11 @@ func (i *implementerDocument) HybridSearch(ctx context.Context, params HybridSea // Fields: // - DocumentIds: The list of the documents' ids to delete. The maximum size of the array is 20. // - Filter: (Optional) Filter documents by [Filter] conditions to delete. +// - Limit: (Optional) Limit the number of documents deleted. type DeleteDocumentParams struct { DocumentIds []string Filter *Filter + Limit int64 } type DeleteDocumentResult struct { @@ -401,6 +417,21 @@ func (i *implementerDocument) Update(ctx context.Context, param UpdateDocumentPa return i.flat.Update(ctx, i.database.DatabaseName, i.collection.CollectionName, param) } +// [Count] counts the number of documents in a collection that satisfy the specified filter conditions. +// +// Parameters: +// - ctx: A context.Context object controls the request's lifetime, allowing for the request +// to be canceled or to timeout according to the context's deadline. +// - param: A [CountDocumentParams] object that includes the other parameters for counting documents' operation. +// See [CountDocumentParams] for more information. +// +// Notes: The name of the database and the name of collection are from the fields of [implementerDocument]. +// +// Returns a pointer to a [CountDocumentResult] object or an error. +func (i *implementerDocument) Count(ctx context.Context, params ...CountDocumentParams) (*CountDocumentResult, error) { + return i.flat.Count(ctx, i.database.DatabaseName, i.collection.CollectionName, params...) +} + type Document struct { Id string `json:"id"` Vector []float32 `json:"vector"` @@ -733,6 +764,8 @@ func (i *implementerFlatDocument) HybridSearch(ctx context.Context, databaseName req.Search.AnnParams[i].Data = make([]interface{}, 0) if vec, ok := annParam.Data.([]float32); ok { req.Search.AnnParams[i].Data = append(req.Search.AnnParams[i].Data, vec) + } else if text, ok := annParam.Data.(string); ok { + req.Search.AnnParams[i].Data = append(req.Search.AnnParams[i].Data, text) } else { return nil, fmt.Errorf("hybridSearch failed, because of AnnParam.Data field type, " + "which must be []float32") @@ -771,6 +804,8 @@ func (i *implementerFlatDocument) HybridSearch(ctx context.Context, databaseName if matchParam.Limit != nil { req.Search.Match[i].Limit = *matchParam.Limit } + req.Search.Match[i].TerminateAfter = matchParam.TerminateAfter + req.Search.Match[i].CutoffFrequency = matchParam.CutoffFrequency break } @@ -844,6 +879,7 @@ func (i *implementerFlatDocument) Delete(ctx context.Context, databaseName, coll req.Query = &document.QueryCond{ DocumentIds: param.DocumentIds, Filter: param.Filter.Cond(), + Limit: param.Limit, } res := new(document.DeleteRes) @@ -923,6 +959,55 @@ func (i *implementerFlatDocument) Update(ctx context.Context, databaseName, coll return result, nil } +// [CountDocumentParams] holds the parameters for counting the number of documents to a collection based on the [Filter] conditions. +// +// Fields: +// - CountFilter: (Optional) Filter documents by [Filter] conditions to count. +type CountDocumentParams struct { + CountFilter *Filter +} + +// [CountDocumentResult] holds the results for counting the number of documents to a collection based on the [Filter] conditions. +// +// Fields: +// - Count: The number of documents to a collection based on the [Filter]. +type CountDocumentResult struct { + Count uint64 +} + +// [Count] counts the number of documents in a collection that satisfy the specified filter conditions. +// +// Parameters: +// - ctx: A context.Context object controls the request's lifetime, allowing for the request +// to be canceled or to timeout according to the context's deadline. +// - databaseName: The name of the database. +// - collectionName: The name of the collection. +// - param: A [CountDocumentParams] object that includes the other parameters for counting documents' operation. +// See [CountDocumentParams] for more information. +// +// Returns a pointer to a [CountDocumentResult] object or an error. +func (i *implementerFlatDocument) Count(ctx context.Context, databaseName, collectionName string, + params ...CountDocumentParams) (*CountDocumentResult, error) { + req := new(document.CountReq) + req.Database = databaseName + req.Collection = collectionName + req.Query = new(document.CountQueryCond) + + if len(params) != 0 { + param := params[0] + req.Query.Filter = param.CountFilter.Cond() + } + + res := new(document.CountRes) + result := new(CountDocumentResult) + err := i.Request(ctx, req, res) + if err != nil { + return result, err + } + result.Count = res.Count + return result, nil +} + func ConvSliceInterface2SparseVecItem(sv []interface{}) (*encoder.SparseVecItem, error) { svItem := new(encoder.SparseVecItem) diff --git a/tcvectordb/base_index.go b/tcvectordb/base_index.go index 327b5e5..14374dd 100644 --- a/tcvectordb/base_index.go +++ b/tcvectordb/base_index.go @@ -32,6 +32,9 @@ type IndexInterface interface { // [AddIndex] adds scalar field index to an existing collection. AddIndex(ctx context.Context, params ...*AddIndexParams) (err error) + + // [ModifyVectorIndex] modifies vector indexes to an existing collection. + ModifyVectorIndex(ctx context.Context, param ModifyVectorIndexParam) (err error) } type implementerIndex struct { @@ -74,3 +77,8 @@ func (i *implementerIndex) RebuildIndex(ctx context.Context, params ...*RebuildI func (i *implementerIndex) AddIndex(ctx context.Context, params ...*AddIndexParams) error { return i.flat.AddIndex(ctx, i.database.DatabaseName, i.collection.CollectionName, params...) } + +// [ModifyVectorIndex] modifies vector indexes to an existing collection. +func (i *implementerIndex) ModifyVectorIndex(ctx context.Context, param ModifyVectorIndexParam) error { + return i.flat.ModifyVectorIndex(ctx, i.database.DatabaseName, i.collection.CollectionName, param) +} diff --git a/tcvectordb/base_index_flat.go b/tcvectordb/base_index_flat.go index 8888209..b8beb88 100644 --- a/tcvectordb/base_index_flat.go +++ b/tcvectordb/base_index_flat.go @@ -17,6 +17,9 @@ type FlatIndexInterface interface { // [AddIndex] adds scalar field index to an existing collection. AddIndex(ctx context.Context, databaseName, collectionName string, params ...*AddIndexParams) (err error) + + // [ModifyVectorIndex] modifies vector indexes to an existing collection. + ModifyVectorIndex(ctx context.Context, databaseName, collectionName string, param ModifyVectorIndexParam) (err error) } type implementerFlatIndex struct { @@ -49,6 +52,11 @@ type AddIndexParams struct { BuildExistedData *bool } +type ModifyVectorIndexParam struct { + VectorIndexes []VectorIndex + RebuildRules *index.RebuildRules +} + // [RebuildIndex] rebuilds all indexes under the specified collection. // // Parameters: @@ -115,3 +123,31 @@ func (i *implementerFlatIndex) AddIndex(ctx context.Context, databaseName, colle } return nil } + +// [ModifyVectorIndex] modifies vector indexes to an existing collection. +func (i *implementerFlatIndex) ModifyVectorIndex(ctx context.Context, databaseName, collectionName string, param ModifyVectorIndexParam) error { + req := new(index.ModifyVectorIndexReq) + req.Database = databaseName + req.Collection = collectionName + + for _, v := range param.VectorIndexes { + var column api.IndexColumn + column.FieldName = v.FieldName + column.FieldType = string(v.FieldType) + column.IndexType = string(v.IndexType) + column.MetricType = string(v.MetricType) + column.Dimension = v.Dimension + + optionParams(&column, v) + + req.VectorIndexes = append(req.VectorIndexes, &column) + } + req.RebuildRules = param.RebuildRules + + res := new(index.ModifyVectorIndexReq) + err := i.Request(ctx, req, res) + if err != nil { + return err + } + return nil +} diff --git a/tcvectordb/consts.go b/tcvectordb/consts.go index 03d9280..a06e924 100644 --- a/tcvectordb/consts.go +++ b/tcvectordb/consts.go @@ -31,6 +31,8 @@ const ( IVF_SQ4 IndexType = "IVF_SQ4" IVF_SQ8 IndexType = "IVF_SQ8" IVF_SQ16 IndexType = "IVF_SQ16" + BIN_FLAT IndexType = "BIN_FLAT" + BIN_HNSW IndexType = "BIN_HNSW" // scalar index type PRIMARY IndexType = "primaryKey" @@ -41,9 +43,10 @@ const ( type MetricType string const ( - L2 MetricType = "L2" - IP MetricType = "IP" - COSINE MetricType = "COSINE" + L2 MetricType = "L2" + IP MetricType = "IP" + COSINE MetricType = "COSINE" + HAMMING MetricType = "Hamming" ) type FieldType string @@ -54,6 +57,7 @@ const ( Array FieldType = "array" Vector FieldType = "vector" SparseVector FieldType = "sparseVector" + BinaryVector FieldType = "binary_vector" ) type EmbeddingModel string @@ -136,6 +140,7 @@ var ( const ( ERR_UNDEFINED_DATABASE = 15301 ERR_UNDEFINED_COLLECTION = 15302 + ERR_SYNTAX_ERROR = 15000 ) type RerankMethod string diff --git a/tcvectordb/olama/olama.pb.go b/tcvectordb/olama/olama.pb.go index 543af0f..5b5dc1f 100644 --- a/tcvectordb/olama/olama.pb.go +++ b/tcvectordb/olama/olama.pb.go @@ -2479,6 +2479,7 @@ type CreateCollectionRequest struct { Version int64 `protobuf:"varint,12,opt,name=version,proto3" json:"version,omitempty"` TtlConfig *TTLConfig `protobuf:"bytes,13,opt,name=ttlConfig,proto3" json:"ttlConfig,omitempty"` FilterIndexConfig *FilterIndexConfig `protobuf:"bytes,14,opt,name=filterIndexConfig,proto3" json:"filterIndexConfig,omitempty"` + DocumentCount uint64 `protobuf:"varint,15,opt,name=document_count,json=documentCount,proto3" json:"document_count,omitempty"` } func (x *CreateCollectionRequest) Reset() { @@ -2611,6 +2612,13 @@ func (x *CreateCollectionRequest) GetFilterIndexConfig() *FilterIndexConfig { return nil } +func (x *CreateCollectionRequest) GetDocumentCount() uint64 { + if x != nil { + return x.DocumentCount + } + return 0 +} + type CreateCollectionResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3874,6 +3882,140 @@ func (x *QueryResponse) GetCount() uint64 { return 0 } +type CountRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"` + Collection string `protobuf:"bytes,2,opt,name=collection,proto3" json:"collection,omitempty"` + Query *QueryCond `protobuf:"bytes,3,opt,name=query,proto3" json:"query,omitempty"` +} + +func (x *CountRequest) Reset() { + *x = CountRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_olama_proto_msgTypes[45] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CountRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CountRequest) ProtoMessage() {} + +func (x *CountRequest) ProtoReflect() protoreflect.Message { + mi := &file_olama_proto_msgTypes[45] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CountRequest.ProtoReflect.Descriptor instead. +func (*CountRequest) Descriptor() ([]byte, []int) { + return file_olama_proto_rawDescGZIP(), []int{45} +} + +func (x *CountRequest) GetDatabase() string { + if x != nil { + return x.Database + } + return "" +} + +func (x *CountRequest) GetCollection() string { + if x != nil { + return x.Collection + } + return "" +} + +func (x *CountRequest) GetQuery() *QueryCond { + if x != nil { + return x.Query + } + return nil +} + +type CountResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Redirect string `protobuf:"bytes,3,opt,name=redirect,proto3" json:"redirect,omitempty"` + Count uint64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"` +} + +func (x *CountResponse) Reset() { + *x = CountResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_olama_proto_msgTypes[46] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CountResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CountResponse) ProtoMessage() {} + +func (x *CountResponse) ProtoReflect() protoreflect.Message { + mi := &file_olama_proto_msgTypes[46] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CountResponse.ProtoReflect.Descriptor instead. +func (*CountResponse) Descriptor() ([]byte, []int) { + return file_olama_proto_rawDescGZIP(), []int{46} +} + +func (x *CountResponse) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *CountResponse) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *CountResponse) GetRedirect() string { + if x != nil { + return x.Redirect + } + return "" +} + +func (x *CountResponse) GetCount() uint64 { + if x != nil { + return x.Count + } + return 0 +} + type SearchResult struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3885,7 +4027,7 @@ type SearchResult struct { func (x *SearchResult) Reset() { *x = SearchResult{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[45] + mi := &file_olama_proto_msgTypes[47] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3898,7 +4040,7 @@ func (x *SearchResult) String() string { func (*SearchResult) ProtoMessage() {} func (x *SearchResult) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[45] + mi := &file_olama_proto_msgTypes[47] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3911,7 +4053,7 @@ func (x *SearchResult) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchResult.ProtoReflect.Descriptor instead. func (*SearchResult) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{45} + return file_olama_proto_rawDescGZIP(), []int{47} } func (x *SearchResult) GetDocuments() []*Document { @@ -3934,7 +4076,7 @@ type SearchParams struct { func (x *SearchParams) Reset() { *x = SearchParams{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[46] + mi := &file_olama_proto_msgTypes[48] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -3947,7 +4089,7 @@ func (x *SearchParams) String() string { func (*SearchParams) ProtoMessage() {} func (x *SearchParams) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[46] + mi := &file_olama_proto_msgTypes[48] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -3960,7 +4102,7 @@ func (x *SearchParams) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchParams.ProtoReflect.Descriptor instead. func (*SearchParams) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{46} + return file_olama_proto_rawDescGZIP(), []int{48} } func (x *SearchParams) GetNprobe() uint32 { @@ -3995,7 +4137,7 @@ type VectorArray struct { func (x *VectorArray) Reset() { *x = VectorArray{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[47] + mi := &file_olama_proto_msgTypes[49] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4008,7 +4150,7 @@ func (x *VectorArray) String() string { func (*VectorArray) ProtoMessage() {} func (x *VectorArray) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[47] + mi := &file_olama_proto_msgTypes[49] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4021,7 +4163,7 @@ func (x *VectorArray) ProtoReflect() protoreflect.Message { // Deprecated: Use VectorArray.ProtoReflect.Descriptor instead. func (*VectorArray) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{47} + return file_olama_proto_rawDescGZIP(), []int{49} } func (x *VectorArray) GetVector() []float32 { @@ -4036,18 +4178,19 @@ type AnnData struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName,omitempty"` // 字段名称 - Data []*VectorArray `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"` // 使用向量值检索 - DocumentIds []string `protobuf:"bytes,3,rep,name=documentIds,proto3" json:"documentIds,omitempty"` // 使用向量id检索 - Params *SearchParams `protobuf:"bytes,4,opt,name=params,proto3" json:"params,omitempty"` // 搜索参数 - Limit uint32 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"` // 结果数量 - DataExpr []string `protobuf:"bytes,6,rep,name=data_expr,json=dataExpr,proto3" json:"data_expr,omitempty"` // 表达式搜索 + FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName,omitempty"` // 字段名称 + Data []*VectorArray `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"` // 使用向量值检索 + DocumentIds []string `protobuf:"bytes,3,rep,name=documentIds,proto3" json:"documentIds,omitempty"` // 使用向量id检索 + Params *SearchParams `protobuf:"bytes,4,opt,name=params,proto3" json:"params,omitempty"` // 搜索参数 + Limit uint32 `protobuf:"varint,5,opt,name=limit,proto3" json:"limit,omitempty"` // 结果数量 + DataExpr []string `protobuf:"bytes,6,rep,name=data_expr,json=dataExpr,proto3" json:"data_expr,omitempty"` // 表达式搜索 + EmbeddingItems []string `protobuf:"bytes,7,rep,name=embeddingItems,proto3" json:"embeddingItems,omitempty"` // 使用embedding字段检索 } func (x *AnnData) Reset() { *x = AnnData{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[48] + mi := &file_olama_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4060,7 +4203,7 @@ func (x *AnnData) String() string { func (*AnnData) ProtoMessage() {} func (x *AnnData) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[48] + mi := &file_olama_proto_msgTypes[50] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4073,7 +4216,7 @@ func (x *AnnData) ProtoReflect() protoreflect.Message { // Deprecated: Use AnnData.ProtoReflect.Descriptor instead. func (*AnnData) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{48} + return file_olama_proto_rawDescGZIP(), []int{50} } func (x *AnnData) GetFieldName() string { @@ -4118,6 +4261,13 @@ func (x *AnnData) GetDataExpr() []string { return nil } +func (x *AnnData) GetEmbeddingItems() []string { + if x != nil { + return x.EmbeddingItems + } + return nil +} + type SparseVectorArray struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4129,7 +4279,7 @@ type SparseVectorArray struct { func (x *SparseVectorArray) Reset() { *x = SparseVectorArray{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[49] + mi := &file_olama_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4142,7 +4292,7 @@ func (x *SparseVectorArray) String() string { func (*SparseVectorArray) ProtoMessage() {} func (x *SparseVectorArray) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[49] + mi := &file_olama_proto_msgTypes[51] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4155,7 +4305,7 @@ func (x *SparseVectorArray) ProtoReflect() protoreflect.Message { // Deprecated: Use SparseVectorArray.ProtoReflect.Descriptor instead. func (*SparseVectorArray) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{49} + return file_olama_proto_rawDescGZIP(), []int{51} } func (x *SparseVectorArray) GetSpVector() []*SparseVecItem { @@ -4165,6 +4315,61 @@ func (x *SparseVectorArray) GetSpVector() []*SparseVecItem { return nil } +type SparseSearchParams struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TerminateAfter uint32 `protobuf:"varint,1,opt,name=terminateAfter,proto3" json:"terminateAfter,omitempty"` // 搜索到指定数量的结果就终止 + CutoffFrequency float64 `protobuf:"fixed64,2,opt,name=cutoffFrequency,proto3" json:"cutoffFrequency,omitempty"` // 全文检索时过滤掉高频词 +} + +func (x *SparseSearchParams) Reset() { + *x = SparseSearchParams{} + if protoimpl.UnsafeEnabled { + mi := &file_olama_proto_msgTypes[52] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SparseSearchParams) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SparseSearchParams) ProtoMessage() {} + +func (x *SparseSearchParams) ProtoReflect() protoreflect.Message { + mi := &file_olama_proto_msgTypes[52] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SparseSearchParams.ProtoReflect.Descriptor instead. +func (*SparseSearchParams) Descriptor() ([]byte, []int) { + return file_olama_proto_rawDescGZIP(), []int{52} +} + +func (x *SparseSearchParams) GetTerminateAfter() uint32 { + if x != nil { + return x.TerminateAfter + } + return 0 +} + +func (x *SparseSearchParams) GetCutoffFrequency() float64 { + if x != nil { + return x.CutoffFrequency + } + return 0 +} + type SparseData struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4173,12 +4378,13 @@ type SparseData struct { FieldName string `protobuf:"bytes,1,opt,name=fieldName,proto3" json:"fieldName,omitempty"` // 字段名称 Data []*SparseVectorArray `protobuf:"bytes,2,rep,name=data,proto3" json:"data,omitempty"` // 使用向量值检索 Limit uint32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` // 结果数量 + Params *SparseSearchParams `protobuf:"bytes,4,opt,name=params,proto3" json:"params,omitempty"` // 搜索参数 } func (x *SparseData) Reset() { *x = SparseData{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[50] + mi := &file_olama_proto_msgTypes[53] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4191,7 +4397,7 @@ func (x *SparseData) String() string { func (*SparseData) ProtoMessage() {} func (x *SparseData) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[50] + mi := &file_olama_proto_msgTypes[53] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4204,7 +4410,7 @@ func (x *SparseData) ProtoReflect() protoreflect.Message { // Deprecated: Use SparseData.ProtoReflect.Descriptor instead. func (*SparseData) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{50} + return file_olama_proto_rawDescGZIP(), []int{53} } func (x *SparseData) GetFieldName() string { @@ -4228,6 +4434,13 @@ func (x *SparseData) GetLimit() uint32 { return 0 } +func (x *SparseData) GetParams() *SparseSearchParams { + if x != nil { + return x.Params + } + return nil +} + type RerankParams struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4241,7 +4454,7 @@ type RerankParams struct { func (x *RerankParams) Reset() { *x = RerankParams{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[51] + mi := &file_olama_proto_msgTypes[54] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4254,7 +4467,7 @@ func (x *RerankParams) String() string { func (*RerankParams) ProtoMessage() {} func (x *RerankParams) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[51] + mi := &file_olama_proto_msgTypes[54] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4267,7 +4480,7 @@ func (x *RerankParams) ProtoReflect() protoreflect.Message { // Deprecated: Use RerankParams.ProtoReflect.Descriptor instead. func (*RerankParams) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{51} + return file_olama_proto_rawDescGZIP(), []int{54} } func (x *RerankParams) GetMethod() string { @@ -4314,7 +4527,7 @@ type SearchCond struct { func (x *SearchCond) Reset() { *x = SearchCond{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[52] + mi := &file_olama_proto_msgTypes[55] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4327,7 +4540,7 @@ func (x *SearchCond) String() string { func (*SearchCond) ProtoMessage() {} func (x *SearchCond) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[52] + mi := &file_olama_proto_msgTypes[55] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4340,7 +4553,7 @@ func (x *SearchCond) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchCond.ProtoReflect.Descriptor instead. func (*SearchCond) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{52} + return file_olama_proto_rawDescGZIP(), []int{55} } func (x *SearchCond) GetVectors() []*VectorArray { @@ -4448,7 +4661,7 @@ type SearchRequest struct { func (x *SearchRequest) Reset() { *x = SearchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[53] + mi := &file_olama_proto_msgTypes[56] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4461,7 +4674,7 @@ func (x *SearchRequest) String() string { func (*SearchRequest) ProtoMessage() {} func (x *SearchRequest) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[53] + mi := &file_olama_proto_msgTypes[56] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4474,7 +4687,7 @@ func (x *SearchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchRequest.ProtoReflect.Descriptor instead. func (*SearchRequest) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{53} + return file_olama_proto_rawDescGZIP(), []int{56} } func (x *SearchRequest) GetDatabase() string { @@ -4518,7 +4731,7 @@ type Filter struct { func (x *Filter) Reset() { *x = Filter{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[54] + mi := &file_olama_proto_msgTypes[57] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4531,7 +4744,7 @@ func (x *Filter) String() string { func (*Filter) ProtoMessage() {} func (x *Filter) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[54] + mi := &file_olama_proto_msgTypes[57] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4544,7 +4757,7 @@ func (x *Filter) ProtoReflect() protoreflect.Message { // Deprecated: Use Filter.ProtoReflect.Descriptor instead. func (*Filter) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{54} + return file_olama_proto_rawDescGZIP(), []int{57} } func (x *Filter) GetExpr() string { @@ -4580,7 +4793,7 @@ type RoaringBinary struct { func (x *RoaringBinary) Reset() { *x = RoaringBinary{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[55] + mi := &file_olama_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4593,7 +4806,7 @@ func (x *RoaringBinary) String() string { func (*RoaringBinary) ProtoMessage() {} func (x *RoaringBinary) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[55] + mi := &file_olama_proto_msgTypes[58] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4606,7 +4819,7 @@ func (x *RoaringBinary) ProtoReflect() protoreflect.Message { // Deprecated: Use RoaringBinary.ProtoReflect.Descriptor instead. func (*RoaringBinary) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{55} + return file_olama_proto_rawDescGZIP(), []int{58} } func (x *RoaringBinary) GetSize() int64 { @@ -4639,7 +4852,7 @@ type SearchResponse struct { func (x *SearchResponse) Reset() { *x = SearchResponse{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[56] + mi := &file_olama_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4652,7 +4865,7 @@ func (x *SearchResponse) String() string { func (*SearchResponse) ProtoMessage() {} func (x *SearchResponse) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[56] + mi := &file_olama_proto_msgTypes[59] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4665,7 +4878,7 @@ func (x *SearchResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use SearchResponse.ProtoReflect.Descriptor instead. func (*SearchResponse) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{56} + return file_olama_proto_rawDescGZIP(), []int{59} } func (x *SearchResponse) GetCode() int32 { @@ -4722,7 +4935,7 @@ type DatabaseRequest struct { func (x *DatabaseRequest) Reset() { *x = DatabaseRequest{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[57] + mi := &file_olama_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4735,7 +4948,7 @@ func (x *DatabaseRequest) String() string { func (*DatabaseRequest) ProtoMessage() {} func (x *DatabaseRequest) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[57] + mi := &file_olama_proto_msgTypes[60] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4748,7 +4961,7 @@ func (x *DatabaseRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DatabaseRequest.ProtoReflect.Descriptor instead. func (*DatabaseRequest) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{57} + return file_olama_proto_rawDescGZIP(), []int{60} } func (x *DatabaseRequest) GetDatabase() string { @@ -4781,7 +4994,7 @@ type DatabaseResponse struct { func (x *DatabaseResponse) Reset() { *x = DatabaseResponse{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[58] + mi := &file_olama_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4794,7 +5007,7 @@ func (x *DatabaseResponse) String() string { func (*DatabaseResponse) ProtoMessage() {} func (x *DatabaseResponse) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[58] + mi := &file_olama_proto_msgTypes[61] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4807,7 +5020,7 @@ func (x *DatabaseResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use DatabaseResponse.ProtoReflect.Descriptor instead. func (*DatabaseResponse) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{58} + return file_olama_proto_rawDescGZIP(), []int{61} } func (x *DatabaseResponse) GetCode() int32 { @@ -4861,7 +5074,7 @@ type GetVersionRequest struct { func (x *GetVersionRequest) Reset() { *x = GetVersionRequest{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[59] + mi := &file_olama_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4874,7 +5087,7 @@ func (x *GetVersionRequest) String() string { func (*GetVersionRequest) ProtoMessage() {} func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[59] + mi := &file_olama_proto_msgTypes[62] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4887,7 +5100,7 @@ func (x *GetVersionRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionRequest.ProtoReflect.Descriptor instead. func (*GetVersionRequest) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{59} + return file_olama_proto_rawDescGZIP(), []int{62} } type GetVersionResponse struct { @@ -4902,7 +5115,7 @@ type GetVersionResponse struct { func (x *GetVersionResponse) Reset() { *x = GetVersionResponse{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[60] + mi := &file_olama_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4915,7 +5128,7 @@ func (x *GetVersionResponse) String() string { func (*GetVersionResponse) ProtoMessage() {} func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[60] + mi := &file_olama_proto_msgTypes[63] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4928,7 +5141,7 @@ func (x *GetVersionResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use GetVersionResponse.ProtoReflect.Descriptor instead. func (*GetVersionResponse) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{60} + return file_olama_proto_rawDescGZIP(), []int{63} } func (x *GetVersionResponse) GetTimestamp() int64 { @@ -4945,6 +5158,140 @@ func (x *GetVersionResponse) GetKernalVersion() int64 { return 0 } +type ModifyVectorIndexRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Database string `protobuf:"bytes,1,opt,name=database,proto3" json:"database,omitempty"` + Collection string `protobuf:"bytes,2,opt,name=collection,proto3" json:"collection,omitempty"` + VectorIndexes map[string]*IndexColumn `protobuf:"bytes,3,rep,name=vectorIndexes,proto3" json:"vectorIndexes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + RebuildRules *RebuildIndexRequest `protobuf:"bytes,4,opt,name=rebuildRules,proto3" json:"rebuildRules,omitempty"` +} + +func (x *ModifyVectorIndexRequest) Reset() { + *x = ModifyVectorIndexRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_olama_proto_msgTypes[64] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ModifyVectorIndexRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModifyVectorIndexRequest) ProtoMessage() {} + +func (x *ModifyVectorIndexRequest) ProtoReflect() protoreflect.Message { + mi := &file_olama_proto_msgTypes[64] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModifyVectorIndexRequest.ProtoReflect.Descriptor instead. +func (*ModifyVectorIndexRequest) Descriptor() ([]byte, []int) { + return file_olama_proto_rawDescGZIP(), []int{64} +} + +func (x *ModifyVectorIndexRequest) GetDatabase() string { + if x != nil { + return x.Database + } + return "" +} + +func (x *ModifyVectorIndexRequest) GetCollection() string { + if x != nil { + return x.Collection + } + return "" +} + +func (x *ModifyVectorIndexRequest) GetVectorIndexes() map[string]*IndexColumn { + if x != nil { + return x.VectorIndexes + } + return nil +} + +func (x *ModifyVectorIndexRequest) GetRebuildRules() *RebuildIndexRequest { + if x != nil { + return x.RebuildRules + } + return nil +} + +type ModifyVectorIndexResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Msg string `protobuf:"bytes,2,opt,name=msg,proto3" json:"msg,omitempty"` + Redirect string `protobuf:"bytes,3,opt,name=redirect,proto3" json:"redirect,omitempty"` +} + +func (x *ModifyVectorIndexResponse) Reset() { + *x = ModifyVectorIndexResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_olama_proto_msgTypes[65] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ModifyVectorIndexResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ModifyVectorIndexResponse) ProtoMessage() {} + +func (x *ModifyVectorIndexResponse) ProtoReflect() protoreflect.Message { + mi := &file_olama_proto_msgTypes[65] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ModifyVectorIndexResponse.ProtoReflect.Descriptor instead. +func (*ModifyVectorIndexResponse) Descriptor() ([]byte, []int) { + return file_olama_proto_rawDescGZIP(), []int{65} +} + +func (x *ModifyVectorIndexResponse) GetCode() int32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *ModifyVectorIndexResponse) GetMsg() string { + if x != nil { + return x.Msg + } + return "" +} + +func (x *ModifyVectorIndexResponse) GetRedirect() string { + if x != nil { + return x.Redirect + } + return "" +} + type AddIndexRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4959,7 +5306,7 @@ type AddIndexRequest struct { func (x *AddIndexRequest) Reset() { *x = AddIndexRequest{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[61] + mi := &file_olama_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4972,7 +5319,7 @@ func (x *AddIndexRequest) String() string { func (*AddIndexRequest) ProtoMessage() {} func (x *AddIndexRequest) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[61] + mi := &file_olama_proto_msgTypes[66] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4985,7 +5332,7 @@ func (x *AddIndexRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use AddIndexRequest.ProtoReflect.Descriptor instead. func (*AddIndexRequest) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{61} + return file_olama_proto_rawDescGZIP(), []int{66} } func (x *AddIndexRequest) GetDatabase() string { @@ -5029,7 +5376,7 @@ type AddIndexResponse struct { func (x *AddIndexResponse) Reset() { *x = AddIndexResponse{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[62] + mi := &file_olama_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5042,7 +5389,7 @@ func (x *AddIndexResponse) String() string { func (*AddIndexResponse) ProtoMessage() {} func (x *AddIndexResponse) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[62] + mi := &file_olama_proto_msgTypes[67] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5055,7 +5402,7 @@ func (x *AddIndexResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use AddIndexResponse.ProtoReflect.Descriptor instead. func (*AddIndexResponse) Descriptor() ([]byte, []int) { - return file_olama_proto_rawDescGZIP(), []int{62} + return file_olama_proto_rawDescGZIP(), []int{67} } func (x *AddIndexResponse) GetCode() int32 { @@ -5090,7 +5437,7 @@ type Field_StringArray struct { func (x *Field_StringArray) Reset() { *x = Field_StringArray{} if protoimpl.UnsafeEnabled { - mi := &file_olama_proto_msgTypes[64] + mi := &file_olama_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5103,7 +5450,7 @@ func (x *Field_StringArray) String() string { func (*Field_StringArray) ProtoMessage() {} func (x *Field_StringArray) ProtoReflect() protoreflect.Message { - mi := &file_olama_proto_msgTypes[64] + mi := &file_olama_proto_msgTypes[69] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5462,7 +5809,7 @@ var file_olama_proto_rawDesc = []byte{ 0x09, 0x52, 0x12, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x57, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1c, 0x0a, 0x09, 0x6d, 0x61, 0x78, 0x53, 0x74, 0x72, 0x4c, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x6d, 0x61, 0x78, 0x53, 0x74, 0x72, - 0x4c, 0x65, 0x6e, 0x22, 0xa7, 0x05, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, + 0x4c, 0x65, 0x6e, 0x22, 0xce, 0x05, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, @@ -5499,326 +5846,381 @@ var file_olama_proto_rawDesc = []byte{ 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x11, 0x66, 0x69, 0x6c, 0x74, - 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0x4e, 0x0a, - 0x0c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x82, 0x01, - 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, - 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, - 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x23, - 0x0a, 0x0d, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, 0x41, 0x6c, - 0x69, 0x61, 0x73, 0x22, 0x80, 0x01, 0x0a, 0x16, 0x44, 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x19, 0x54, 0x72, 0x75, 0x6e, 0x63, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, + 0x65, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x25, 0x0a, + 0x0e, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x1a, 0x4e, 0x0a, 0x0c, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0x82, 0x01, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8e, 0x01, 0x0a, 0x15, 0x44, 0x72, + 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, + 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, + 0x14, 0x0a, 0x05, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x66, 0x6f, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x77, 0x69, 0x74, 0x68, 0x6f, 0x75, 0x74, + 0x5f, 0x61, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x77, 0x69, + 0x74, 0x68, 0x6f, 0x75, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x22, 0x80, 0x01, 0x0a, 0x16, 0x44, + 0x72, 0x6f, 0x70, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, + 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8e, 0x01, + 0x0a, 0x19, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x35, 0x0a, 0x17, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, + 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x6e, 0x6e, 0x5f, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x6f, 0x6e, 0x6c, 0x79, 0x54, 0x72, + 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, 0x6e, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x84, + 0x01, 0x0a, 0x1a, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, + 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe5, 0x01, 0x0a, 0x13, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, + 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, + 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, + 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x64, 0x72, 0x6f, + 0x70, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, + 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, + 0x74, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, + 0x72, 0x61, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, + 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x69, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x63, + 0x65, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x73, 0x0a, + 0x14, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, + 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, + 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, + 0x64, 0x73, 0x22, 0xc2, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x35, 0x0a, 0x17, 0x6f, 0x6e, 0x6c, 0x79, 0x5f, 0x74, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, - 0x65, 0x5f, 0x61, 0x6e, 0x6e, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x08, 0x52, 0x14, 0x6f, 0x6e, 0x6c, 0x79, 0x54, 0x72, 0x75, 0x6e, 0x63, 0x61, 0x74, 0x65, 0x41, - 0x6e, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x84, 0x01, 0x0a, 0x1a, 0x54, 0x72, 0x75, 0x6e, - 0x63, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, + 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, 0x75, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, + 0x26, 0x0a, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x6f, 0x64, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x4d, 0x6f, 0x64, 0x65, 0x22, 0x33, 0x0a, 0x12, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, + 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x65, 0x64, 0x22, 0xdf, 0x01, 0x0a, + 0x0e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, + 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, + 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, + 0x67, 0x12, 0x4b, 0x0a, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x65, + 0x78, 0x74, 0x72, 0x61, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x6d, 0x62, 0x65, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x9c, + 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, + 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x12, 0x27, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, + 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xdf, 0x01, + 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, + 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, + 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, + 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x6d, 0x62, + 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x22, + 0x73, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, + 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, + 0x75, 0x65, 0x72, 0x79, 0x22, 0x78, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xe5, - 0x01, 0x0a, 0x13, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x11, 0x64, 0x72, 0x6f, 0x70, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, - 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x11, 0x64, - 0x72, 0x6f, 0x70, 0x42, 0x65, 0x66, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, - 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x05, 0x52, 0x08, 0x74, 0x68, 0x72, 0x6f, 0x74, 0x74, 0x6c, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x72, 0x61, 0x69, - 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x72, 0x65, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, - 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x22, 0x73, 0x0a, 0x14, 0x52, 0x65, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, + 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8f, + 0x02, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x0b, + 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x1a, + 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, + 0x52, 0x08, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, + 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x14, + 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, + 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, + 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, + 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, + 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, + 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, + 0x96, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, + 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x72, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, 0x72, + 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x67, 0x0a, 0x0d, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, + 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3d, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, + 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, + 0x65, 0x6e, 0x74, 0x73, 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x6e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x0e, 0x0a, 0x02, + 0x65, 0x66, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x22, 0x25, 0x0a, 0x0b, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, + 0x72, 0x61, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x02, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0xf9, 0x01, 0x0a, 0x07, + 0x41, 0x6e, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, + 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, + 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, + 0x2b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, + 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, + 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x45, 0x78, 0x70, 0x72, 0x12, + 0x26, 0x0a, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, + 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x46, 0x0a, 0x11, 0x53, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x31, 0x0a, 0x09, + 0x73, 0x70, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, + 0x63, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x73, 0x70, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, + 0x66, 0x0a, 0x12, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, + 0x74, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x74, + 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x41, 0x66, 0x74, 0x65, 0x72, 0x12, 0x28, 0x0a, + 0x0f, 0x63, 0x75, 0x74, 0x6f, 0x66, 0x66, 0x46, 0x72, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0f, 0x63, 0x75, 0x74, 0x6f, 0x66, 0x66, 0x46, 0x72, + 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xa1, 0x01, 0x0a, 0x0a, 0x53, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, + 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x2c, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x31, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, + 0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x22, 0xb3, 0x01, 0x0a, 0x0c, + 0x52, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x12, 0x3a, 0x0a, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x52, 0x65, + 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x12, 0x13, 0x0a, 0x05, 0x72, 0x72, 0x66, 0x5f, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x04, 0x72, 0x72, 0x66, 0x4b, 0x1a, 0x3a, 0x0a, 0x0c, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0xfc, 0x03, 0x0a, 0x0a, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, + 0x12, 0x2c, 0x0a, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x07, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x20, + 0x0a, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, + 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, + 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, + 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, + 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x66, 0x69, 0x65, + 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, + 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x20, 0x0a, 0x03, 0x61, 0x6e, 0x6e, 0x18, 0x0a, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, 0x6e, 0x6e, 0x44, 0x61, + 0x74, 0x61, 0x52, 0x03, 0x61, 0x6e, 0x6e, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x72, 0x73, + 0x65, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, + 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x44, 0x61, 0x74, 0x61, 0x52, 0x06, 0x73, 0x70, 0x61, 0x72, + 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0d, 0x72, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, + 0x61, 0x2e, 0x52, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, + 0x72, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x32, 0x0a, 0x14, + 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x74, 0x72, + 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x22, 0xa0, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, + 0x0a, 0x06, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, + 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x6f, 0x6e, + 0x64, 0x52, 0x06, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x61, + 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, + 0x6e, 0x63, 0x79, 0x22, 0x48, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, + 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, + 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x02, 0x52, 0x06, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x37, 0x0a, + 0x0d, 0x52, 0x6f, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x12, + 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, + 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xe8, 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, + 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, + 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, + 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, + 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, + 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x14, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, + 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, + 0x6f, 0x22, 0x56, 0x0a, 0x0f, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, + 0x12, 0x27, 0x0a, 0x06, 0x64, 0x62, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, + 0x65, 0x52, 0x06, 0x64, 0x62, 0x54, 0x79, 0x70, 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x10, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x74, 0x61, 0x73, 0x6b, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x07, 0x74, 0x61, 0x73, 0x6b, 0x49, 0x64, 0x73, 0x22, 0xc2, 0x01, 0x0a, 0x0d, - 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, - 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x62, - 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, - 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x4d, 0x6f, 0x64, 0x65, - 0x22, 0x33, 0x0a, 0x12, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, - 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, - 0x75, 0x73, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x55, 0x73, 0x65, 0x64, 0x22, 0xdf, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x73, 0x65, 0x72, 0x74, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, - 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, - 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x14, 0x65, 0x6d, - 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, - 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, - 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x9c, 0x01, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x27, 0x0a, - 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, - 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xdf, 0x01, 0x0a, 0x0e, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x14, 0x65, - 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, 0x69, - 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, - 0x61, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, 0x61, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, - 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x73, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x78, 0x0a, - 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x24, + 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x1a, 0x4c, 0x0a, 0x09, 0x49, + 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, + 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, + 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x59, + 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x6b, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xc6, 0x02, 0x0a, 0x18, 0x4d, 0x6f, + 0x64, 0x69, 0x66, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x58, 0x0a, 0x0d, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, + 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x76, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x12, 0x3e, 0x0a, 0x0c, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0c, + 0x72, 0x65, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x1a, 0x54, 0x0a, 0x12, + 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x28, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x49, 0x6e, 0x64, 0x65, + 0x78, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, + 0x38, 0x01, 0x22, 0x5d, 0x0a, 0x19, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x8f, 0x02, 0x0a, 0x09, 0x51, 0x75, 0x65, 0x72, - 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, - 0x74, 0x49, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x04, 0x52, 0x08, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x49, 0x64, 0x73, 0x12, 0x26, 0x0a, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, - 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, - 0x74, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, - 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, - 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x46, - 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, - 0x65, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, - 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0x9c, 0x01, 0x0a, 0x0c, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x51, 0x75, - 0x65, 0x72, 0x79, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x12, 0x28, - 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, - 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x96, 0x01, 0x0a, 0x0d, 0x51, 0x75, 0x65, - 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, - 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, - 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x09, - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, - 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x22, 0x3d, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x12, 0x2d, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, - 0x22, 0x4e, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x6e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x06, 0x6e, 0x70, 0x72, 0x6f, 0x62, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x65, 0x66, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x65, 0x66, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x64, 0x69, - 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, - 0x22, 0x25, 0x0a, 0x0b, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, - 0x16, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x03, 0x28, 0x02, 0x52, - 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0xd1, 0x01, 0x0a, 0x07, 0x41, 0x6e, 0x6e, 0x44, - 0x61, 0x74, 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x26, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, - 0x72, 0x61, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, - 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, - 0x52, 0x06, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, - 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x1b, - 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x65, 0x78, 0x70, 0x72, 0x18, 0x06, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x45, 0x78, 0x70, 0x72, 0x22, 0x46, 0x0a, 0x11, 0x53, - 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, - 0x12, 0x31, 0x0a, 0x09, 0x73, 0x70, 0x5f, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x70, 0x61, 0x72, - 0x73, 0x65, 0x56, 0x65, 0x63, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x08, 0x73, 0x70, 0x56, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x22, 0x6e, 0x0a, 0x0a, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x44, 0x61, 0x74, - 0x61, 0x12, 0x1c, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x2c, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, - 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x22, 0xb3, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x3a, 0x0a, 0x07, - 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, - 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x2e, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x77, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x12, 0x13, 0x0a, 0x05, 0x72, 0x72, 0x66, 0x5f, - 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x72, 0x72, 0x66, 0x4b, 0x1a, 0x3a, 0x0a, - 0x0c, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfc, 0x03, 0x0a, 0x0a, 0x53, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, 0x12, 0x2c, 0x0a, 0x07, 0x76, 0x65, 0x63, 0x74, - 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, - 0x61, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x07, 0x76, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, - 0x6e, 0x74, 0x49, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x6f, 0x63, - 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x73, 0x12, 0x2b, 0x0a, 0x06, 0x70, 0x61, 0x72, 0x61, - 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, - 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x06, 0x70, - 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x26, 0x0a, - 0x0e, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x56, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x22, 0x0a, 0x0c, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x73, 0x12, - 0x26, 0x0a, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, - 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x20, 0x0a, - 0x03, 0x61, 0x6e, 0x6e, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x6f, 0x6c, 0x61, - 0x6d, 0x61, 0x2e, 0x41, 0x6e, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x03, 0x61, 0x6e, 0x6e, 0x12, - 0x29, 0x0a, 0x06, 0x73, 0x70, 0x61, 0x72, 0x73, 0x65, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x11, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x52, 0x06, 0x73, 0x70, 0x61, 0x72, 0x73, 0x65, 0x12, 0x38, 0x0a, 0x0d, 0x72, 0x65, - 0x72, 0x61, 0x6e, 0x6b, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x52, 0x65, 0x72, 0x61, 0x6e, 0x6b, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0c, 0x72, 0x65, 0x72, 0x61, 0x6e, 0x6b, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x73, 0x12, 0x32, 0x0a, 0x14, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, - 0x53, 0x70, 0x61, 0x72, 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x14, 0x72, 0x65, 0x74, 0x72, 0x69, 0x65, 0x76, 0x65, 0x53, 0x70, 0x61, 0x72, - 0x73, 0x65, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x22, 0xa0, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, - 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x29, 0x0a, 0x06, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x43, 0x6f, 0x6e, 0x64, 0x52, 0x06, 0x73, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x12, 0x28, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, - 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x64, - 0x43, 0x6f, 0x6e, 0x73, 0x69, 0x73, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x22, 0x48, 0x0a, 0x06, 0x46, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x61, 0x64, - 0x69, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x02, 0x52, 0x06, 0x72, 0x61, 0x64, 0x69, 0x75, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x04, 0x73, 0x69, 0x7a, 0x65, 0x22, 0x37, 0x0a, 0x0d, 0x52, 0x6f, 0x61, 0x72, 0x69, 0x6e, 0x67, - 0x42, 0x69, 0x6e, 0x61, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xe8, - 0x01, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, 0x67, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x64, 0x69, 0x72, - 0x65, 0x63, 0x74, 0x12, 0x2d, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x04, - 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x77, 0x61, 0x72, 0x6e, 0x69, 0x6e, 0x67, 0x12, 0x4b, 0x0a, 0x14, - 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x5f, 0x65, 0x78, 0x74, 0x72, 0x61, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6f, 0x6c, 0x61, - 0x6d, 0x61, 0x2e, 0x45, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x45, 0x78, 0x74, 0x72, - 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x12, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x69, 0x6e, 0x67, - 0x45, 0x78, 0x74, 0x72, 0x61, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x56, 0x0a, 0x0f, 0x44, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x06, 0x64, 0x62, 0x54, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, - 0x2e, 0x44, 0x61, 0x74, 0x61, 0x54, 0x79, 0x70, 0x65, 0x52, 0x06, 0x64, 0x62, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x9d, 0x02, 0x0a, 0x10, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6d, 0x73, - 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x73, 0x67, 0x12, 0x1a, 0x0a, 0x08, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, - 0x72, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x64, 0x61, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x61, 0x66, 0x66, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, - 0x66, 0x66, 0x65, 0x63, 0x74, 0x65, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x04, - 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6f, 0x6c, 0x61, - 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x69, - 0x6e, 0x66, 0x6f, 0x1a, 0x4c, 0x0a, 0x09, 0x49, 0x6e, 0x66, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, - 0x65, 0x79, 0x12, 0x29, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, - 0x01, 0x22, 0x13, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x59, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1c, 0x0a, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x25, 0x0a, 0x0e, 0x6b, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x0d, 0x6b, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x22, 0x88, 0x02, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, + 0x74, 0x22, 0x88, 0x02, 0x0a, 0x0f, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, @@ -5869,7 +6271,7 @@ var file_olama_proto_rawDesc = []byte{ 0x59, 0x50, 0x45, 0x5f, 0x55, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x02, 0x2a, 0x2b, 0x0a, 0x10, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x45, 0x4c, 0x45, 0x4d, 0x45, 0x4e, 0x54, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x32, 0xd9, 0x0a, 0x0a, 0x0c, 0x53, 0x65, + 0x5f, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x32, 0xa3, 0x0c, 0x0a, 0x0c, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x45, 0x6e, 0x67, 0x69, 0x6e, 0x65, 0x12, 0x3e, 0x0a, 0x08, 0x73, 0x65, 0x74, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, @@ -5931,32 +6333,45 @@ var file_olama_proto_rawDesc = []byte{ 0x79, 0x62, 0x72, 0x69, 0x64, 0x5f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x65, 0x6c, - 0x65, 0x12, 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x41, - 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, - 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, - 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x3f, 0x0a, 0x0c, 0x64, 0x72, 0x6f, 0x70, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, - 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3c, 0x0a, 0x0e, 0x6b, 0x65, 0x79, + 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x14, 0x2e, 0x6f, 0x6c, + 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x33, 0x0a, 0x04, 0x64, 0x65, 0x6c, 0x65, 0x12, + 0x14, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x05, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x13, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6f, 0x6c, 0x61, + 0x6d, 0x61, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, + 0x73, 0x65, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6f, 0x6c, 0x61, + 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x0c, 0x64, 0x72, 0x6f, 0x70, 0x44, 0x61, 0x74, 0x61, 0x62, + 0x61, 0x73, 0x65, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, - 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x61, 0x64, 0x64, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, 0x64, 0x64, - 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6f, - 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x0c, 0x5a, 0x07, 0x2e, 0x3b, 0x6f, 0x6c, 0x61, 0x6d, 0x61, - 0x80, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x0d, 0x6c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, + 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x42, 0x0a, 0x0b, 0x67, 0x65, 0x74, 0x5f, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x47, 0x65, + 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x19, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x47, 0x65, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x08, 0x61, 0x64, + 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x16, 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, + 0x64, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, + 0x2e, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x41, 0x64, 0x64, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x6d, 0x6f, 0x64, 0x69, 0x66, + 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1f, 0x2e, 0x6f, + 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x56, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, + 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x2e, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, + 0x0c, 0x5a, 0x07, 0x2e, 0x3b, 0x6f, 0x6c, 0x61, 0x6d, 0x61, 0x80, 0x01, 0x01, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5972,7 +6387,7 @@ func file_olama_proto_rawDescGZIP() []byte { } var file_olama_proto_enumTypes = make([]protoimpl.EnumInfo, 6) -var file_olama_proto_msgTypes = make([]protoimpl.MessageInfo, 71) +var file_olama_proto_msgTypes = make([]protoimpl.MessageInfo, 77) var file_olama_proto_goTypes = []interface{}{ (ShardDataState)(0), // 0: olama.ShardDataState (DataType)(0), // 1: olama.DataType @@ -6025,44 +6440,50 @@ var file_olama_proto_goTypes = []interface{}{ (*QueryCond)(nil), // 48: olama.QueryCond (*QueryRequest)(nil), // 49: olama.QueryRequest (*QueryResponse)(nil), // 50: olama.QueryResponse - (*SearchResult)(nil), // 51: olama.SearchResult - (*SearchParams)(nil), // 52: olama.SearchParams - (*VectorArray)(nil), // 53: olama.VectorArray - (*AnnData)(nil), // 54: olama.AnnData - (*SparseVectorArray)(nil), // 55: olama.SparseVectorArray - (*SparseData)(nil), // 56: olama.SparseData - (*RerankParams)(nil), // 57: olama.RerankParams - (*SearchCond)(nil), // 58: olama.SearchCond - (*SearchRequest)(nil), // 59: olama.SearchRequest - (*Filter)(nil), // 60: olama.Filter - (*RoaringBinary)(nil), // 61: olama.RoaringBinary - (*SearchResponse)(nil), // 62: olama.SearchResponse - (*DatabaseRequest)(nil), // 63: olama.DatabaseRequest - (*DatabaseResponse)(nil), // 64: olama.DatabaseResponse - (*GetVersionRequest)(nil), // 65: olama.GetVersionRequest - (*GetVersionResponse)(nil), // 66: olama.GetVersionResponse - (*AddIndexRequest)(nil), // 67: olama.AddIndexRequest - (*AddIndexResponse)(nil), // 68: olama.AddIndexResponse - nil, // 69: olama.Document.FieldsEntry - (*Field_StringArray)(nil), // 70: olama.Field.StringArray - nil, // 71: olama.CollectionConf.FieldMetasEntry - nil, // 72: olama.CollectionConf.OptionsEntry - nil, // 73: olama.CreateCollectionRequest.IndexesEntry - nil, // 74: olama.RerankParams.WeightsEntry - nil, // 75: olama.DatabaseResponse.InfoEntry - nil, // 76: olama.AddIndexRequest.IndexesEntry + (*CountRequest)(nil), // 51: olama.CountRequest + (*CountResponse)(nil), // 52: olama.CountResponse + (*SearchResult)(nil), // 53: olama.SearchResult + (*SearchParams)(nil), // 54: olama.SearchParams + (*VectorArray)(nil), // 55: olama.VectorArray + (*AnnData)(nil), // 56: olama.AnnData + (*SparseVectorArray)(nil), // 57: olama.SparseVectorArray + (*SparseSearchParams)(nil), // 58: olama.SparseSearchParams + (*SparseData)(nil), // 59: olama.SparseData + (*RerankParams)(nil), // 60: olama.RerankParams + (*SearchCond)(nil), // 61: olama.SearchCond + (*SearchRequest)(nil), // 62: olama.SearchRequest + (*Filter)(nil), // 63: olama.Filter + (*RoaringBinary)(nil), // 64: olama.RoaringBinary + (*SearchResponse)(nil), // 65: olama.SearchResponse + (*DatabaseRequest)(nil), // 66: olama.DatabaseRequest + (*DatabaseResponse)(nil), // 67: olama.DatabaseResponse + (*GetVersionRequest)(nil), // 68: olama.GetVersionRequest + (*GetVersionResponse)(nil), // 69: olama.GetVersionResponse + (*ModifyVectorIndexRequest)(nil), // 70: olama.ModifyVectorIndexRequest + (*ModifyVectorIndexResponse)(nil), // 71: olama.ModifyVectorIndexResponse + (*AddIndexRequest)(nil), // 72: olama.AddIndexRequest + (*AddIndexResponse)(nil), // 73: olama.AddIndexResponse + nil, // 74: olama.Document.FieldsEntry + (*Field_StringArray)(nil), // 75: olama.Field.StringArray + nil, // 76: olama.CollectionConf.FieldMetasEntry + nil, // 77: olama.CollectionConf.OptionsEntry + nil, // 78: olama.CreateCollectionRequest.IndexesEntry + nil, // 79: olama.RerankParams.WeightsEntry + nil, // 80: olama.DatabaseResponse.InfoEntry + nil, // 81: olama.ModifyVectorIndexRequest.VectorIndexesEntry + nil, // 82: olama.AddIndexRequest.IndexesEntry } var file_olama_proto_depIdxs = []int32{ - 69, // 0: olama.Document.fields:type_name -> olama.Document.FieldsEntry + 74, // 0: olama.Document.fields:type_name -> olama.Document.FieldsEntry 8, // 1: olama.Document.sparse_vector:type_name -> olama.SparseVecItem - 70, // 2: olama.Field.val_str_arr:type_name -> olama.Field.StringArray + 75, // 2: olama.Field.val_str_arr:type_name -> olama.Field.StringArray 0, // 3: olama.ShardState.data_state:type_name -> olama.ShardDataState 9, // 4: olama.Shard.state:type_name -> olama.ShardState 1, // 5: olama.DatabaseItem.db_type:type_name -> olama.DataType 2, // 6: olama.CollectionConf.metric:type_name -> olama.IndexMetricType 3, // 7: olama.CollectionConf.engine:type_name -> olama.IndexEngineType - 71, // 8: olama.CollectionConf.field_metas:type_name -> olama.CollectionConf.FieldMetasEntry - 72, // 9: olama.CollectionConf.options:type_name -> olama.CollectionConf.OptionsEntry + 76, // 8: olama.CollectionConf.field_metas:type_name -> olama.CollectionConf.FieldMetasEntry + 77, // 9: olama.CollectionConf.options:type_name -> olama.CollectionConf.OptionsEntry 13, // 10: olama.CollectionConf.embedding_params:type_name -> olama.EmbeddingParams 1, // 11: olama.CollectionConf.data_type:type_name -> olama.DataType 17, // 12: olama.CollectionConf.ttlConfig:type_name -> olama.TTLConfig @@ -6080,7 +6501,7 @@ var file_olama_proto_depIdxs = []int32{ 33, // 24: olama.ListCollectionsResponse.collections:type_name -> olama.CreateCollectionRequest 19, // 25: olama.ListCollectionsResponse.states:type_name -> olama.CollectionState 29, // 26: olama.IndexColumn.params:type_name -> olama.IndexParams - 73, // 27: olama.CreateCollectionRequest.indexes:type_name -> olama.CreateCollectionRequest.IndexesEntry + 78, // 27: olama.CreateCollectionRequest.indexes:type_name -> olama.CreateCollectionRequest.IndexesEntry 31, // 28: olama.CreateCollectionRequest.indexStatus:type_name -> olama.indexStatus 13, // 29: olama.CreateCollectionRequest.embeddingParams:type_name -> olama.EmbeddingParams 17, // 30: olama.CreateCollectionRequest.ttlConfig:type_name -> olama.TTLConfig @@ -6093,73 +6514,84 @@ var file_olama_proto_depIdxs = []int32{ 48, // 37: olama.DeleteRequest.query:type_name -> olama.QueryCond 48, // 38: olama.QueryRequest.query:type_name -> olama.QueryCond 6, // 39: olama.QueryResponse.documents:type_name -> olama.Document - 6, // 40: olama.SearchResult.documents:type_name -> olama.Document - 53, // 41: olama.AnnData.data:type_name -> olama.VectorArray - 52, // 42: olama.AnnData.params:type_name -> olama.SearchParams - 8, // 43: olama.SparseVectorArray.sp_vector:type_name -> olama.SparseVecItem - 55, // 44: olama.SparseData.data:type_name -> olama.SparseVectorArray - 74, // 45: olama.RerankParams.weights:type_name -> olama.RerankParams.WeightsEntry - 53, // 46: olama.SearchCond.vectors:type_name -> olama.VectorArray - 52, // 47: olama.SearchCond.params:type_name -> olama.SearchParams - 54, // 48: olama.SearchCond.ann:type_name -> olama.AnnData - 56, // 49: olama.SearchCond.sparse:type_name -> olama.SparseData - 57, // 50: olama.SearchCond.rerank_params:type_name -> olama.RerankParams - 58, // 51: olama.SearchRequest.search:type_name -> olama.SearchCond - 51, // 52: olama.SearchResponse.results:type_name -> olama.SearchResult - 42, // 53: olama.SearchResponse.embedding_extra_info:type_name -> olama.EmbeddingExtraInfo - 1, // 54: olama.DatabaseRequest.dbType:type_name -> olama.DataType - 75, // 55: olama.DatabaseResponse.info:type_name -> olama.DatabaseResponse.InfoEntry - 76, // 56: olama.AddIndexRequest.indexes:type_name -> olama.AddIndexRequest.IndexesEntry - 7, // 57: olama.Document.FieldsEntry.value:type_name -> olama.Field - 15, // 58: olama.CollectionConf.FieldMetasEntry.value:type_name -> olama.FieldMeta - 30, // 59: olama.CreateCollectionRequest.IndexesEntry.value:type_name -> olama.IndexColumn - 12, // 60: olama.DatabaseResponse.InfoEntry.value:type_name -> olama.DatabaseItem - 30, // 61: olama.AddIndexRequest.IndexesEntry.value:type_name -> olama.IndexColumn - 20, // 62: olama.SearchEngine.setAlias:input_type -> olama.AddAliasRequest - 23, // 63: olama.SearchEngine.getAlias:input_type -> olama.GetAliasRequest - 21, // 64: olama.SearchEngine.deleteAlias:input_type -> olama.RemoveAliasRequest - 33, // 65: olama.SearchEngine.createCollection:input_type -> olama.CreateCollectionRequest - 35, // 66: olama.SearchEngine.dropCollection:input_type -> olama.DropCollectionRequest - 37, // 67: olama.SearchEngine.truncateCollection:input_type -> olama.TruncateCollectionRequest - 25, // 68: olama.SearchEngine.describeCollection:input_type -> olama.DescribeCollectionRequest - 27, // 69: olama.SearchEngine.listCollections:input_type -> olama.ListCollectionsRequest - 39, // 70: olama.SearchEngine.rebuildIndex:input_type -> olama.RebuildIndexRequest - 41, // 71: olama.SearchEngine.upsert:input_type -> olama.UpsertRequest - 44, // 72: olama.SearchEngine.update:input_type -> olama.UpdateRequest - 49, // 73: olama.SearchEngine.query:input_type -> olama.QueryRequest - 59, // 74: olama.SearchEngine.search:input_type -> olama.SearchRequest - 59, // 75: olama.SearchEngine.hybrid_search:input_type -> olama.SearchRequest - 46, // 76: olama.SearchEngine.dele:input_type -> olama.DeleteRequest - 63, // 77: olama.SearchEngine.createDatabase:input_type -> olama.DatabaseRequest - 63, // 78: olama.SearchEngine.dropDatabase:input_type -> olama.DatabaseRequest - 63, // 79: olama.SearchEngine.listDatabases:input_type -> olama.DatabaseRequest - 65, // 80: olama.SearchEngine.get_version:input_type -> olama.GetVersionRequest - 67, // 81: olama.SearchEngine.addIndex:input_type -> olama.AddIndexRequest - 22, // 82: olama.SearchEngine.setAlias:output_type -> olama.UpdateAliasResponse - 24, // 83: olama.SearchEngine.getAlias:output_type -> olama.GetAliasResponse - 22, // 84: olama.SearchEngine.deleteAlias:output_type -> olama.UpdateAliasResponse - 34, // 85: olama.SearchEngine.createCollection:output_type -> olama.CreateCollectionResponse - 36, // 86: olama.SearchEngine.dropCollection:output_type -> olama.DropCollectionResponse - 38, // 87: olama.SearchEngine.truncateCollection:output_type -> olama.TruncateCollectionResponse - 26, // 88: olama.SearchEngine.describeCollection:output_type -> olama.DescribeCollectionResponse - 28, // 89: olama.SearchEngine.listCollections:output_type -> olama.ListCollectionsResponse - 40, // 90: olama.SearchEngine.rebuildIndex:output_type -> olama.RebuildIndexResponse - 43, // 91: olama.SearchEngine.upsert:output_type -> olama.UpsertResponse - 45, // 92: olama.SearchEngine.update:output_type -> olama.UpdateResponse - 50, // 93: olama.SearchEngine.query:output_type -> olama.QueryResponse - 62, // 94: olama.SearchEngine.search:output_type -> olama.SearchResponse - 62, // 95: olama.SearchEngine.hybrid_search:output_type -> olama.SearchResponse - 47, // 96: olama.SearchEngine.dele:output_type -> olama.DeleteResponse - 64, // 97: olama.SearchEngine.createDatabase:output_type -> olama.DatabaseResponse - 64, // 98: olama.SearchEngine.dropDatabase:output_type -> olama.DatabaseResponse - 64, // 99: olama.SearchEngine.listDatabases:output_type -> olama.DatabaseResponse - 66, // 100: olama.SearchEngine.get_version:output_type -> olama.GetVersionResponse - 68, // 101: olama.SearchEngine.addIndex:output_type -> olama.AddIndexResponse - 82, // [82:102] is the sub-list for method output_type - 62, // [62:82] is the sub-list for method input_type - 62, // [62:62] is the sub-list for extension type_name - 62, // [62:62] is the sub-list for extension extendee - 0, // [0:62] is the sub-list for field type_name + 48, // 40: olama.CountRequest.query:type_name -> olama.QueryCond + 6, // 41: olama.SearchResult.documents:type_name -> olama.Document + 55, // 42: olama.AnnData.data:type_name -> olama.VectorArray + 54, // 43: olama.AnnData.params:type_name -> olama.SearchParams + 8, // 44: olama.SparseVectorArray.sp_vector:type_name -> olama.SparseVecItem + 57, // 45: olama.SparseData.data:type_name -> olama.SparseVectorArray + 58, // 46: olama.SparseData.params:type_name -> olama.SparseSearchParams + 79, // 47: olama.RerankParams.weights:type_name -> olama.RerankParams.WeightsEntry + 55, // 48: olama.SearchCond.vectors:type_name -> olama.VectorArray + 54, // 49: olama.SearchCond.params:type_name -> olama.SearchParams + 56, // 50: olama.SearchCond.ann:type_name -> olama.AnnData + 59, // 51: olama.SearchCond.sparse:type_name -> olama.SparseData + 60, // 52: olama.SearchCond.rerank_params:type_name -> olama.RerankParams + 61, // 53: olama.SearchRequest.search:type_name -> olama.SearchCond + 53, // 54: olama.SearchResponse.results:type_name -> olama.SearchResult + 42, // 55: olama.SearchResponse.embedding_extra_info:type_name -> olama.EmbeddingExtraInfo + 1, // 56: olama.DatabaseRequest.dbType:type_name -> olama.DataType + 80, // 57: olama.DatabaseResponse.info:type_name -> olama.DatabaseResponse.InfoEntry + 81, // 58: olama.ModifyVectorIndexRequest.vectorIndexes:type_name -> olama.ModifyVectorIndexRequest.VectorIndexesEntry + 39, // 59: olama.ModifyVectorIndexRequest.rebuildRules:type_name -> olama.RebuildIndexRequest + 82, // 60: olama.AddIndexRequest.indexes:type_name -> olama.AddIndexRequest.IndexesEntry + 7, // 61: olama.Document.FieldsEntry.value:type_name -> olama.Field + 15, // 62: olama.CollectionConf.FieldMetasEntry.value:type_name -> olama.FieldMeta + 30, // 63: olama.CreateCollectionRequest.IndexesEntry.value:type_name -> olama.IndexColumn + 12, // 64: olama.DatabaseResponse.InfoEntry.value:type_name -> olama.DatabaseItem + 30, // 65: olama.ModifyVectorIndexRequest.VectorIndexesEntry.value:type_name -> olama.IndexColumn + 30, // 66: olama.AddIndexRequest.IndexesEntry.value:type_name -> olama.IndexColumn + 20, // 67: olama.SearchEngine.setAlias:input_type -> olama.AddAliasRequest + 23, // 68: olama.SearchEngine.getAlias:input_type -> olama.GetAliasRequest + 21, // 69: olama.SearchEngine.deleteAlias:input_type -> olama.RemoveAliasRequest + 33, // 70: olama.SearchEngine.createCollection:input_type -> olama.CreateCollectionRequest + 35, // 71: olama.SearchEngine.dropCollection:input_type -> olama.DropCollectionRequest + 37, // 72: olama.SearchEngine.truncateCollection:input_type -> olama.TruncateCollectionRequest + 25, // 73: olama.SearchEngine.describeCollection:input_type -> olama.DescribeCollectionRequest + 27, // 74: olama.SearchEngine.listCollections:input_type -> olama.ListCollectionsRequest + 39, // 75: olama.SearchEngine.rebuildIndex:input_type -> olama.RebuildIndexRequest + 41, // 76: olama.SearchEngine.upsert:input_type -> olama.UpsertRequest + 44, // 77: olama.SearchEngine.update:input_type -> olama.UpdateRequest + 49, // 78: olama.SearchEngine.query:input_type -> olama.QueryRequest + 62, // 79: olama.SearchEngine.search:input_type -> olama.SearchRequest + 62, // 80: olama.SearchEngine.hybrid_search:input_type -> olama.SearchRequest + 62, // 81: olama.SearchEngine.keyword_search:input_type -> olama.SearchRequest + 46, // 82: olama.SearchEngine.dele:input_type -> olama.DeleteRequest + 51, // 83: olama.SearchEngine.count:input_type -> olama.CountRequest + 66, // 84: olama.SearchEngine.createDatabase:input_type -> olama.DatabaseRequest + 66, // 85: olama.SearchEngine.dropDatabase:input_type -> olama.DatabaseRequest + 66, // 86: olama.SearchEngine.listDatabases:input_type -> olama.DatabaseRequest + 68, // 87: olama.SearchEngine.get_version:input_type -> olama.GetVersionRequest + 72, // 88: olama.SearchEngine.addIndex:input_type -> olama.AddIndexRequest + 70, // 89: olama.SearchEngine.modifyVectorIndex:input_type -> olama.ModifyVectorIndexRequest + 22, // 90: olama.SearchEngine.setAlias:output_type -> olama.UpdateAliasResponse + 24, // 91: olama.SearchEngine.getAlias:output_type -> olama.GetAliasResponse + 22, // 92: olama.SearchEngine.deleteAlias:output_type -> olama.UpdateAliasResponse + 34, // 93: olama.SearchEngine.createCollection:output_type -> olama.CreateCollectionResponse + 36, // 94: olama.SearchEngine.dropCollection:output_type -> olama.DropCollectionResponse + 38, // 95: olama.SearchEngine.truncateCollection:output_type -> olama.TruncateCollectionResponse + 26, // 96: olama.SearchEngine.describeCollection:output_type -> olama.DescribeCollectionResponse + 28, // 97: olama.SearchEngine.listCollections:output_type -> olama.ListCollectionsResponse + 40, // 98: olama.SearchEngine.rebuildIndex:output_type -> olama.RebuildIndexResponse + 43, // 99: olama.SearchEngine.upsert:output_type -> olama.UpsertResponse + 45, // 100: olama.SearchEngine.update:output_type -> olama.UpdateResponse + 50, // 101: olama.SearchEngine.query:output_type -> olama.QueryResponse + 65, // 102: olama.SearchEngine.search:output_type -> olama.SearchResponse + 65, // 103: olama.SearchEngine.hybrid_search:output_type -> olama.SearchResponse + 62, // 104: olama.SearchEngine.keyword_search:output_type -> olama.SearchRequest + 47, // 105: olama.SearchEngine.dele:output_type -> olama.DeleteResponse + 52, // 106: olama.SearchEngine.count:output_type -> olama.CountResponse + 67, // 107: olama.SearchEngine.createDatabase:output_type -> olama.DatabaseResponse + 67, // 108: olama.SearchEngine.dropDatabase:output_type -> olama.DatabaseResponse + 67, // 109: olama.SearchEngine.listDatabases:output_type -> olama.DatabaseResponse + 69, // 110: olama.SearchEngine.get_version:output_type -> olama.GetVersionResponse + 73, // 111: olama.SearchEngine.addIndex:output_type -> olama.AddIndexResponse + 71, // 112: olama.SearchEngine.modifyVectorIndex:output_type -> olama.ModifyVectorIndexResponse + 90, // [90:113] is the sub-list for method output_type + 67, // [67:90] is the sub-list for method input_type + 67, // [67:67] is the sub-list for extension type_name + 67, // [67:67] is the sub-list for extension extendee + 0, // [0:67] is the sub-list for field type_name } func init() { file_olama_proto_init() } @@ -6709,7 +7141,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[45].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchResult); i { + switch v := v.(*CountRequest); i { case 0: return &v.state case 1: @@ -6721,7 +7153,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[46].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchParams); i { + switch v := v.(*CountResponse); i { case 0: return &v.state case 1: @@ -6733,7 +7165,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[47].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VectorArray); i { + switch v := v.(*SearchResult); i { case 0: return &v.state case 1: @@ -6745,7 +7177,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[48].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AnnData); i { + switch v := v.(*SearchParams); i { case 0: return &v.state case 1: @@ -6757,7 +7189,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[49].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SparseVectorArray); i { + switch v := v.(*VectorArray); i { case 0: return &v.state case 1: @@ -6769,7 +7201,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[50].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SparseData); i { + switch v := v.(*AnnData); i { case 0: return &v.state case 1: @@ -6781,7 +7213,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[51].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RerankParams); i { + switch v := v.(*SparseVectorArray); i { case 0: return &v.state case 1: @@ -6793,7 +7225,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[52].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchCond); i { + switch v := v.(*SparseSearchParams); i { case 0: return &v.state case 1: @@ -6805,7 +7237,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[53].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchRequest); i { + switch v := v.(*SparseData); i { case 0: return &v.state case 1: @@ -6817,7 +7249,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[54].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Filter); i { + switch v := v.(*RerankParams); i { case 0: return &v.state case 1: @@ -6829,7 +7261,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[55].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RoaringBinary); i { + switch v := v.(*SearchCond); i { case 0: return &v.state case 1: @@ -6841,7 +7273,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[56].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*SearchResponse); i { + switch v := v.(*SearchRequest); i { case 0: return &v.state case 1: @@ -6853,7 +7285,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[57].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DatabaseRequest); i { + switch v := v.(*Filter); i { case 0: return &v.state case 1: @@ -6865,7 +7297,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[58].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DatabaseResponse); i { + switch v := v.(*RoaringBinary); i { case 0: return &v.state case 1: @@ -6877,7 +7309,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[59].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVersionRequest); i { + switch v := v.(*SearchResponse); i { case 0: return &v.state case 1: @@ -6889,7 +7321,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[60].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetVersionResponse); i { + switch v := v.(*DatabaseRequest); i { case 0: return &v.state case 1: @@ -6901,7 +7333,7 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[61].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddIndexRequest); i { + switch v := v.(*DatabaseResponse); i { case 0: return &v.state case 1: @@ -6913,7 +7345,19 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[62].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*AddIndexResponse); i { + switch v := v.(*GetVersionRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_olama_proto_msgTypes[63].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetVersionResponse); i { case 0: return &v.state case 1: @@ -6925,6 +7369,54 @@ func file_olama_proto_init() { } } file_olama_proto_msgTypes[64].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ModifyVectorIndexRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_olama_proto_msgTypes[65].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ModifyVectorIndexResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_olama_proto_msgTypes[66].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddIndexRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_olama_proto_msgTypes[67].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*AddIndexResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_olama_proto_msgTypes[69].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Field_StringArray); i { case 0: return &v.state @@ -6949,7 +7441,7 @@ func file_olama_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_olama_proto_rawDesc, NumEnums: 6, - NumMessages: 71, + NumMessages: 77, NumExtensions: 0, NumServices: 1, }, diff --git a/tcvectordb/olama/olama.proto b/tcvectordb/olama/olama.proto index 9390e91..9797ec4 100644 --- a/tcvectordb/olama/olama.proto +++ b/tcvectordb/olama/olama.proto @@ -276,7 +276,8 @@ message CreateCollectionRequest { EmbeddingParams embeddingParams = 11; int64 version = 12; TTLConfig ttlConfig = 13; - FilterIndexConfig filterIndexConfig = 14; + FilterIndexConfig filterIndexConfig = 14; + uint64 document_count = 15; }; message CreateCollectionResponse { @@ -405,6 +406,20 @@ message QueryResponse { uint64 count = 5; }; +message CountRequest { + string database = 1; + string collection = 2; + QueryCond query = 3; +}; + +message CountResponse { + int32 code = 1; + string msg = 2; + string redirect = 3; + uint64 count = 4; +}; + + message SearchResult { repeated Document documents = 1; } @@ -426,16 +441,23 @@ message AnnData { SearchParams params = 4; // 搜索参数 uint32 limit = 5; // 结果数量 repeated string data_expr = 6; // 表达式搜索 + repeated string embeddingItems = 7; // 使用embedding字段检索 } message SparseVectorArray { repeated SparseVecItem sp_vector = 1; } +message SparseSearchParams { + uint32 terminateAfter = 1; // 搜索到指定数量的结果就终止 + double cutoffFrequency = 2; // 全文检索时过滤掉高频词 +} + message SparseData { string fieldName = 1; // 字段名称 repeated SparseVectorArray data = 2; // 使用向量值检索 uint32 limit = 3; // 结果数量 + SparseSearchParams params = 4; // 搜索参数 } message RerankParams { @@ -509,6 +531,19 @@ message GetVersionResponse { int64 kernal_version = 2; // 4段版本号拼接组成, v1.2.3.4 表示成1002003004 }; +message ModifyVectorIndexRequest { + string database = 1; + string collection = 2; + map vectorIndexes = 3; + RebuildIndexRequest rebuildRules = 4; +}; + +message ModifyVectorIndexResponse { + int32 code = 1; + string msg = 2; + string redirect = 3; +}; + message AddIndexRequest { string database = 1; string collection = 2; @@ -554,8 +589,13 @@ service SearchEngine { rpc search(SearchRequest) returns (SearchResponse); // 混合搜索 rpc hybrid_search(SearchRequest) returns (SearchResponse); + // 关键词检索 + rpc keyword_search(SearchRequest) returns (SearchResponse); // 删除向量 rpc dele(DeleteRequest) returns (DeleteResponse); + // count + rpc count(CountRequest) returns (CountResponse); + // 创建 database rpc createDatabase(DatabaseRequest) returns (DatabaseResponse); @@ -569,4 +609,6 @@ service SearchEngine { // 新增scalar的索引 rpc addIndex(AddIndexRequest) returns (AddIndexResponse); + // 修改index配置 + rpc modifyVectorIndex(ModifyVectorIndexRequest) returns (ModifyVectorIndexResponse); }; \ No newline at end of file diff --git a/tcvectordb/olama/olama_grpc.pb.go b/tcvectordb/olama/olama_grpc.pb.go index 5464a6c..19dc83c 100644 --- a/tcvectordb/olama/olama_grpc.pb.go +++ b/tcvectordb/olama/olama_grpc.pb.go @@ -50,8 +50,12 @@ type SearchEngineClient interface { Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) // 混合搜索 HybridSearch(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) + // 关键词检索 + KeywordSearch(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) // 删除向量 Dele(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) + // count + Count(ctx context.Context, in *CountRequest, opts ...grpc.CallOption) (*CountResponse, error) // 创建 database CreateDatabase(ctx context.Context, in *DatabaseRequest, opts ...grpc.CallOption) (*DatabaseResponse, error) // 删除 database @@ -62,6 +66,8 @@ type SearchEngineClient interface { GetVersion(ctx context.Context, in *GetVersionRequest, opts ...grpc.CallOption) (*GetVersionResponse, error) // 新增scalar的索引 AddIndex(ctx context.Context, in *AddIndexRequest, opts ...grpc.CallOption) (*AddIndexResponse, error) + // 修改index配置 + ModifyVectorIndex(ctx context.Context, in *ModifyVectorIndexRequest, opts ...grpc.CallOption) (*ModifyVectorIndexResponse, error) } type searchEngineClient struct { @@ -198,6 +204,15 @@ func (c *searchEngineClient) HybridSearch(ctx context.Context, in *SearchRequest return out, nil } +func (c *searchEngineClient) KeywordSearch(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error) { + out := new(SearchResponse) + err := c.cc.Invoke(ctx, "/document/keywordSearch", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *searchEngineClient) Dele(ctx context.Context, in *DeleteRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { out := new(DeleteResponse) err := c.cc.Invoke(ctx, "/document/delete", in, out, opts...) @@ -207,6 +222,15 @@ func (c *searchEngineClient) Dele(ctx context.Context, in *DeleteRequest, opts . return out, nil } +func (c *searchEngineClient) Count(ctx context.Context, in *CountRequest, opts ...grpc.CallOption) (*CountResponse, error) { + out := new(CountResponse) + err := c.cc.Invoke(ctx, "/document/count", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *searchEngineClient) CreateDatabase(ctx context.Context, in *DatabaseRequest, opts ...grpc.CallOption) (*DatabaseResponse, error) { out := new(DatabaseResponse) err := c.cc.Invoke(ctx, "/database/create", in, out, opts...) @@ -252,6 +276,15 @@ func (c *searchEngineClient) AddIndex(ctx context.Context, in *AddIndexRequest, return out, nil } +func (c *searchEngineClient) ModifyVectorIndex(ctx context.Context, in *ModifyVectorIndexRequest, opts ...grpc.CallOption) (*ModifyVectorIndexResponse, error) { + out := new(ModifyVectorIndexResponse) + err := c.cc.Invoke(ctx, "/index/modifyVectorIndex", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SearchEngineServer is the server API for SearchEngine service. // All implementations must embed UnimplementedSearchEngineServer // for forward compatibility @@ -284,8 +317,12 @@ type SearchEngineServer interface { Search(context.Context, *SearchRequest) (*SearchResponse, error) // 混合搜索 HybridSearch(context.Context, *SearchRequest) (*SearchResponse, error) + // 关键词检索 + KeywordSearch(context.Context, *SearchRequest) (*SearchRequest, error) // 删除向量 Dele(context.Context, *DeleteRequest) (*DeleteResponse, error) + // count + Count(context.Context, *CountRequest) (*CountResponse, error) // 创建 database CreateDatabase(context.Context, *DatabaseRequest) (*DatabaseResponse, error) // 删除 database @@ -296,6 +333,8 @@ type SearchEngineServer interface { GetVersion(context.Context, *GetVersionRequest) (*GetVersionResponse, error) // 新增scalar的索引 AddIndex(context.Context, *AddIndexRequest) (*AddIndexResponse, error) + // 修改index配置 + ModifyVectorIndex(context.Context, *ModifyVectorIndexRequest) (*ModifyVectorIndexResponse, error) mustEmbedUnimplementedSearchEngineServer() } @@ -345,9 +384,15 @@ func (UnimplementedSearchEngineServer) Search(context.Context, *SearchRequest) ( func (UnimplementedSearchEngineServer) HybridSearch(context.Context, *SearchRequest) (*SearchResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method HybridSearch not implemented") } +func (UnimplementedSearchEngineServer) KeywordSearch(context.Context, *SearchRequest) (*SearchRequest, error) { + return nil, status.Errorf(codes.Unimplemented, "method KeywordSearch not implemented") +} func (UnimplementedSearchEngineServer) Dele(context.Context, *DeleteRequest) (*DeleteResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Dele not implemented") } +func (UnimplementedSearchEngineServer) Count(context.Context, *CountRequest) (*CountResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Count not implemented") +} func (UnimplementedSearchEngineServer) CreateDatabase(context.Context, *DatabaseRequest) (*DatabaseResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method CreateDatabase not implemented") } @@ -363,6 +408,9 @@ func (UnimplementedSearchEngineServer) GetVersion(context.Context, *GetVersionRe func (UnimplementedSearchEngineServer) AddIndex(context.Context, *AddIndexRequest) (*AddIndexResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method AddIndex not implemented") } +func (UnimplementedSearchEngineServer) ModifyVectorIndex(context.Context, *ModifyVectorIndexRequest) (*ModifyVectorIndexResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ModifyVectorIndex not implemented") +} func (UnimplementedSearchEngineServer) mustEmbedUnimplementedSearchEngineServer() {} // UnsafeSearchEngineServer may be embedded to opt out of forward compatibility for this service. @@ -628,6 +676,24 @@ func _SearchEngine_HybridSearch_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _SearchEngine_KeywordSearch_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SearchRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SearchEngineServer).KeywordSearch(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/olama.SearchEngine/keyword_search", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SearchEngineServer).KeywordSearch(ctx, req.(*SearchRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _SearchEngine_Dele_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DeleteRequest) if err := dec(in); err != nil { @@ -646,6 +712,24 @@ func _SearchEngine_Dele_Handler(srv interface{}, ctx context.Context, dec func(i return interceptor(ctx, in, info, handler) } +func _SearchEngine_Count_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CountRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SearchEngineServer).Count(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/olama.SearchEngine/count", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SearchEngineServer).Count(ctx, req.(*CountRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _SearchEngine_CreateDatabase_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(DatabaseRequest) if err := dec(in); err != nil { @@ -736,6 +820,24 @@ func _SearchEngine_AddIndex_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _SearchEngine_ModifyVectorIndex_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ModifyVectorIndexRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SearchEngineServer).ModifyVectorIndex(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/olama.SearchEngine/modifyVectorIndex", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SearchEngineServer).ModifyVectorIndex(ctx, req.(*ModifyVectorIndexRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SearchEngine_ServiceDesc is the grpc.ServiceDesc for SearchEngine service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -799,10 +901,18 @@ var SearchEngine_ServiceDesc = grpc.ServiceDesc{ MethodName: "hybrid_search", Handler: _SearchEngine_HybridSearch_Handler, }, + { + MethodName: "keyword_search", + Handler: _SearchEngine_KeywordSearch_Handler, + }, { MethodName: "dele", Handler: _SearchEngine_Dele_Handler, }, + { + MethodName: "count", + Handler: _SearchEngine_Count_Handler, + }, { MethodName: "createDatabase", Handler: _SearchEngine_CreateDatabase_Handler, @@ -823,7 +933,12 @@ var SearchEngine_ServiceDesc = grpc.ServiceDesc{ MethodName: "addIndex", Handler: _SearchEngine_AddIndex_Handler, }, + { + MethodName: "modifyVectorIndex", + Handler: _SearchEngine_ModifyVectorIndex_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "olama.proto", } + diff --git a/tcvectordb/rpc_base_collection.go b/tcvectordb/rpc_base_collection.go index 18c738c..587b984 100644 --- a/tcvectordb/rpc_base_collection.go +++ b/tcvectordb/rpc_base_collection.go @@ -155,6 +155,21 @@ func (r *rpcImplementerCollection) CreateCollection(ctx context.Context, name st TimeField: param.TtlConfig.TimeField, } } + if param.FilterIndexConfig != nil { + req.FilterIndexConfig = &olama.FilterIndexConfig{ + FilterAll: param.FilterIndexConfig.FilterAll, + FieldsWithoutIndex: param.FilterIndexConfig.FieldsWithoutIndex, + } + + if param.FilterIndexConfig.MaxStrLen != nil { + if *param.FilterIndexConfig.MaxStrLen == 0 { + return nil, fmt.Errorf("code: %d, message: the value of %v cannot be 0", ERR_SYNTAX_ERROR, + "maxStrLen") + } else { + req.FilterIndexConfig.MaxStrLen = *param.FilterIndexConfig.MaxStrLen + } + } + } } _, err := r.rpcClient.CreateCollection(ctx, req) @@ -346,6 +361,14 @@ func (r *rpcImplementerCollection) toCollection(collectionItem *olama.CreateColl coll.TtlConfig = new(TtlConfig) coll.TtlConfig.Enable = collectionItem.TtlConfig.Enable coll.TtlConfig.TimeField = collectionItem.TtlConfig.TimeField + } + if collectionItem.FilterIndexConfig != nil { + coll.FilterIndexConfig = new(FilterIndexConfig) + coll.FilterIndexConfig.FilterAll = collectionItem.FilterIndexConfig.FilterAll + coll.FilterIndexConfig.FieldsWithoutIndex = collectionItem.FilterIndexConfig.FieldsWithoutIndex + coll.FilterIndexConfig.MaxStrLen = &collectionItem.FilterIndexConfig.MaxStrLen + } else { + } if collectionItem.IndexStatus != nil { coll.IndexStatus = IndexStatus{ @@ -359,7 +382,7 @@ func (r *rpcImplementerCollection) toCollection(collectionItem *olama.CreateColl continue } switch index.FieldType { - case string(Vector): + case string(Vector), string(BinaryVector): vector := VectorIndex{} vector.FieldName = index.FieldName vector.FieldType = FieldType(index.FieldType) diff --git a/tcvectordb/rpc_base_document.go b/tcvectordb/rpc_base_document.go index 91bd820..afb1b44 100644 --- a/tcvectordb/rpc_base_document.go +++ b/tcvectordb/rpc_base_document.go @@ -147,6 +147,21 @@ func (r *rpcImplementerDocument) Update(ctx context.Context, param UpdateDocumen return r.flat.Update(ctx, r.database.DatabaseName, r.collection.CollectionName, param) } +// [Count] counts the number of documents in a collection that satisfy the specified filter conditions. +// +// Parameters: +// - ctx: A context.Context object controls the request's lifetime, allowing for the request +// to be canceled or to timeout according to the context's deadline. +// - databaseName: The name of the database. +// - collectionName: The name of the collection. +// - param: A [CountDocumentParams] object that includes the other parameters for counting documents' operation. +// See [CountDocumentParams] for more information. +// +// Returns a pointer to a [CountDocumentResult] object or an error. +func (r *rpcImplementerDocument) Count(ctx context.Context, params ...CountDocumentParams) (*CountDocumentResult, error) { + return r.flat.Count(ctx, r.database.DatabaseName, r.collection.CollectionName, params...) +} + type rpcImplementerFlatDocument struct { SdkClient rpcClient olama.SearchEngineClient @@ -409,16 +424,16 @@ func (r *rpcImplementerFlatDocument) HybridSearch(ctx context.Context, databaseN req.Search.Ann[i].Limit = uint32(*annParam.Limit) } - vectorArray := make([]*olama.VectorArray, 0, len(req.Search.Vectors)) if vec, ok := annParam.Data.([]float32); ok { - vectorArray = append(vectorArray, &olama.VectorArray{Vector: vec}) + req.Search.Ann[i].Data = make([]*olama.VectorArray, 0, len(req.Search.Vectors)) + req.Search.Ann[i].Data = append(req.Search.Ann[i].Data, &olama.VectorArray{Vector: vec}) + } else if text, ok := annParam.Data.(string); ok { + req.Search.Ann[i].EmbeddingItems = append(req.Search.EmbeddingItems, text) } else { - return nil, fmt.Errorf("hybridSearch failed, because of AnnParam.Vectors field type, " + - "which must be []float32") + return nil, fmt.Errorf("hybridSearch failed, because of AnnParam.Data field type, " + + "which must be []float32 or string") } - req.Search.Ann[i].Data = vectorArray - if annParam.Params != nil { req.Search.Ann[i].Params = new(olama.SearchParams) req.Search.Ann[i].Params.Nprobe = annParam.Params.Nprobe @@ -437,7 +452,7 @@ func (r *rpcImplementerFlatDocument) HybridSearch(ctx context.Context, databaseN FieldName: fieldName, }) if matchParam.Limit != nil { - req.Search.Ann[i].Limit = uint32(*matchParam.Limit) + req.Search.Sparse[i].Limit = uint32(*matchParam.Limit) } sparseVectorArray := make([]*olama.SparseVectorArray, 0) @@ -458,6 +473,10 @@ func (r *rpcImplementerFlatDocument) HybridSearch(ctx context.Context, databaseN return nil, fmt.Errorf("hybridSearch failed, because of Match.Data field type, " + "which must be []encoder.SparseVecItem") } + + req.Search.Sparse[i].Params = new(olama.SparseSearchParams) + req.Search.Sparse[i].Params.TerminateAfter = matchParam.TerminateAfter + req.Search.Sparse[i].Params.CutoffFrequency = matchParam.CutoffFrequency break } @@ -535,6 +554,7 @@ func (r *rpcImplementerFlatDocument) Delete(ctx context.Context, databaseName, c Query: &olama.QueryCond{ DocumentIds: param.DocumentIds, Filter: param.Filter.Cond(), + Limit: param.Limit, }, } res, err := r.rpcClient.Dele(ctx, req) @@ -700,3 +720,34 @@ func (r *rpcImplementerFlatDocument) search(ctx context.Context, databaseName, c } return result, nil } + +// [Count] counts the number of documents in a collection that satisfy the specified filter conditions. +// +// Parameters: +// - ctx: A context.Context object controls the request's lifetime, allowing for the request +// to be canceled or to timeout according to the context's deadline. +// - databaseName: The name of the database. +// - collectionName: The name of the collection. +// - param: A [CountDocumentParams] object that includes the other parameters for counting documents' operation. +// See [CountDocumentParams] for more information. +// +// Returns a pointer to a [CountDocumentResult] object or an error. +func (r *rpcImplementerFlatDocument) Count(ctx context.Context, databaseName, collectionName string, + params ...CountDocumentParams) (*CountDocumentResult, error) { + req := &olama.CountRequest{ + Database: databaseName, + Collection: collectionName, + } + + if len(params) != 0 { + param := params[0] + req.Query = &olama.QueryCond{ + Filter: param.CountFilter.Cond(), + } + } + res, err := r.rpcClient.Count(ctx, req) + if err != nil { + return nil, err + } + return &CountDocumentResult{Count: res.Count}, nil +} diff --git a/tcvectordb/rpc_base_index.go b/tcvectordb/rpc_base_index.go index bc8d05f..6025a2e 100644 --- a/tcvectordb/rpc_base_index.go +++ b/tcvectordb/rpc_base_index.go @@ -23,3 +23,8 @@ func (r *rpcImplementerIndex) RebuildIndex(ctx context.Context, params ...*Rebui func (r *rpcImplementerIndex) AddIndex(ctx context.Context, params ...*AddIndexParams) error { return r.flat.AddIndex(ctx, r.database.DatabaseName, r.collection.CollectionName, params...) } + +// [ModifyVectorIndex] modifies vector indexes to an existing collection. +func (r *rpcImplementerIndex) ModifyVectorIndex(ctx context.Context, param ModifyVectorIndexParam) error { + return r.flat.ModifyVectorIndex(ctx, r.database.DatabaseName, r.collection.CollectionName, param) +} diff --git a/tcvectordb/rpc_base_index_flat.go b/tcvectordb/rpc_base_index_flat.go index 7505e05..da4a93f 100644 --- a/tcvectordb/rpc_base_index_flat.go +++ b/tcvectordb/rpc_base_index_flat.go @@ -84,3 +84,39 @@ func (r *rpcImplementerFlatIndex) AddIndex(ctx context.Context, databaseName, co return nil } + +// [ModifyVectorIndex] modifies vector indexes to an existing collection. +func (r *rpcImplementerFlatIndex) ModifyVectorIndex(ctx context.Context, databaseName, collectionName string, + param ModifyVectorIndexParam) error { + req := &olama.ModifyVectorIndexRequest{ + Database: databaseName, + Collection: collectionName, + VectorIndexes: make(map[string]*olama.IndexColumn), + } + + for _, v := range param.VectorIndexes { + column := &olama.IndexColumn{ + FieldName: v.FieldName, + FieldType: string(v.FieldType), + IndexType: string(v.IndexType), + MetricType: string(v.MetricType), + Dimension: v.Dimension, + } + optionRpcParams(column, v) + req.VectorIndexes[v.FieldName] = column + } + + defaultThrottle := int32(1) + if param.RebuildRules == nil { + req.RebuildRules = new(olama.RebuildIndexRequest) + req.RebuildRules.Throttle = defaultThrottle + } else if param.RebuildRules.Throttle == nil { + req.RebuildRules.Throttle = defaultThrottle + } + + _, err := r.rpcClient.ModifyVectorIndex(ctx, req) + if err != nil { + return err + } + return nil +} diff --git a/tcvectordb/utils/binary.go b/tcvectordb/utils/binary.go new file mode 100644 index 0000000..b02cdf4 --- /dev/null +++ b/tcvectordb/utils/binary.go @@ -0,0 +1,28 @@ +package utils + +import ( + "errors" + "strconv" +) + +func BinaryToUint8(binaryArray []byte) ([]float32, error) { + binaryArrayLen := len(binaryArray) + if binaryArrayLen%8 != 0 { + return nil, errors.New("the length of the binaryArray must be a multiple of 8") + } + uint8Array := make([]float32, 0) + for i := 0; i < binaryArrayLen/8; i++ { + arr := binaryArray[i*8 : (i+1)*8] + binaryString := "" + for _, bit := range arr { + binaryString += strconv.Itoa(int(bit)) + } + decimalValue, err := strconv.ParseInt(binaryString, 2, 64) + if err != nil { + return nil, err + } + uint8Value := uint8(decimalValue) & 0xFF + uint8Array = append(uint8Array, float32(uint8Value)) + } + return uint8Array, nil +} diff --git a/tcvectordb/utils/binary_test.go b/tcvectordb/utils/binary_test.go new file mode 100644 index 0000000..a6f903c --- /dev/null +++ b/tcvectordb/utils/binary_test.go @@ -0,0 +1,29 @@ +package utils + +import ( + "encoding/json" + "testing" + + "log" +) + +func Test_ConvertBinaryArray2Uint8Array(t *testing.T) { + binaryA := []byte{1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0} + res, err := BinaryToUint8(binaryA) + if err != nil { + log.Fatalf(err.Error()) + return + } + for _, v := range res { + print(v, " ") + } + println() +} + +func ToJson(any interface{}) string { + bytes, err := json.Marshal(any) + if err != nil { + return "" + } + return string(bytes) +} diff --git a/tcvectordb/version.go b/tcvectordb/version.go index 697a543..1d5db1e 100644 --- a/tcvectordb/version.go +++ b/tcvectordb/version.go @@ -18,4 +18,4 @@ package tcvectordb -const SDKVersion = "v1.4.9" +const SDKVersion = "v1.5.0" diff --git a/test/common.go b/test/common.go index fc7eac4..388d3d1 100644 --- a/test/common.go +++ b/test/common.go @@ -23,8 +23,8 @@ var ( func init() { // 初始化客户端 var err error - cli, err = tcvectordb.NewClient("vdb addr", "root", - "auth key", &tcvectordb.ClientOption{Timeout: 10 * time.Second, + cli, err = tcvectordb.NewClient("", "root", + "", &tcvectordb.ClientOption{Timeout: 10 * time.Second, ReadConsistency: tcvectordb.StrongConsistency}) if err != nil { diff --git a/test/normal_flat_test.go b/test/normal_flat_test.go index c47131c..25e6719 100644 --- a/test/normal_flat_test.go +++ b/test/normal_flat_test.go @@ -237,3 +237,11 @@ func TestFlatDelete(t *testing.T) { printErr(err) log.Printf("Delete result: %+v", res) } + +func TestFlatCount(t *testing.T) { + res, err := cli.Count(ctx, database, collectionName, tcvectordb.CountDocumentParams{ + CountFilter: tcvectordb.NewFilter(`bookName="西游记"`), + }) + printErr(err) + log.Printf("Count result: %+v", res) +} diff --git a/test/normal_test.go b/test/normal_test.go index b6edcad..297e1b0 100644 --- a/test/normal_test.go +++ b/test/normal_test.go @@ -367,6 +367,16 @@ func TestDelete(t *testing.T) { log.Printf("Delete result: %+v", res) } +func TestCount(t *testing.T) { + col := cli.Database(database).Collection(collectionName) + + res, err := col.Count(ctx, tcvectordb.CountDocumentParams{ + CountFilter: tcvectordb.NewFilter(`bookName="西游记"`), + }) + printErr(err) + log.Printf("Count result: %+v", res) +} + func TestReupsertCollection(t *testing.T) { col := cli.Database(database).Collection(collectionName) testLen := int64(10)