diff --git a/search/README.md b/search/README.md index 59c5751..03f492e 100644 --- a/search/README.md +++ b/search/README.md @@ -2,16 +2,13 @@ Indexing and full text search # Search Service -Store and search JSON documents. The Search API provides full indexing and text search. +Store and search JSON records. The Search API provides indexing and full text search. +Search for a word or phrase in a particular field of a record. Combine multiple with +either `AND` or `OR` boolean operators to create complex queries. Powered by [OpenSearch](https://opensearch.org/). -Search for a given word or phrase in a particular field of a document. Combine multiple with either `AND` or `OR` boolean operators to create complex queries. - -## Usage -Documents are inserted using the `/search/index` endpoint. Document fields are automatically indexed with no need to define which fields to index ahead of time. Documents are logically grouped in to `indexes` so you may have an index for customers and one for products. Once documents are inserted you are ready to search, simple as that. - -## Search query language +## Query Language The search API supports a simple query language to let you get to your data quickly without having to learn a complicated language. @@ -41,7 +38,7 @@ or booleans verified == true ``` -You can search on fields that are nested in the document using dot (`.`) as a separator +You can search on fields that are nested in the record using dot (`.`) as a separator ```sql address.city == 'London' diff --git a/search/architecture.md b/search/architecture.md new file mode 100644 index 0000000..5d74ddf --- /dev/null +++ b/search/architecture.md @@ -0,0 +1,79 @@ +Indexing and full text search + +# Search Service + +Store and search JSON records. The Search API provides full indexing and text search. + +Powered by [OpenSearch](https://opensearch.org/). + +Search for a given word or phrase in a particular field of a record. Combine multiple with either `AND` or `OR` boolean operators to create complex queries. + +## Usage + +Records are indexed using the `/search/index` endpoint. Record fields are automatically indexed with no need to define which fields to index ahead of time. Records are logically grouped in to `indexes` so you may have an index for customers and one for products. Once records are inserted you are ready to search, simple as that. + +## Search query language + +The search API supports a simple query language to let you get to your data quickly without having to learn a complicated language. + +The most basic query looks like this + +```sql +key == 'value' +``` + +where you specify a key and a value to find. For example you might want to look for every customer with first name of John + +```sql +first_name == 'John' +``` + +String values support single or double quotes. + +Values can also be numbers + +```sql +age == 37 +``` + +or booleans + +```sql +verified == true +``` + +You can search on fields that are nested in the record using dot (`.`) as a separator + +```sql +address.city == 'London' +``` + +The API also supports wildcard `*` matching to enable scenarios like autocomplete. + +```sql +first_name == 'Joh*' +``` + +In addition to equality `==` the API support greater than or equals `>=` and less than or equals `<=` operators + +```sql +age >= 37 +age <= 37 +``` + +Simple queries can be combined with logical `and` + +```sql +first_name == "John" AND age <= 37 +``` + +or logical `or` +```sql +first_name == "John" OR first_name == "Jane" +``` + +If combining `and` and `or` operations you will need to use parentheses to explicitly define precedence + +```sql +(first_name == "John" OR first_name == "Jane") AND age <= 37 +``` diff --git a/search/examples.json b/search/examples.json index 660074e..4e24612 100644 --- a/search/examples.json +++ b/search/examples.json @@ -1,17 +1,14 @@ { "index": [ { - "title": "Index a document", + "title": "Index a record", "run_check": false, "request": { "index": "customers", - "document": { - "id": "1234", - "contents": { - "name": "John Doe", - "age": 37, - "starsign": "Leo" - } + "data": { + "name": "John Doe", + "age": 37, + "starsign": "Leo" } }, "response": { @@ -20,17 +17,17 @@ ], "search": [ { - "title": "Search for a document", + "title": "Search for a record", "run_check": false, "request": { "index": "customers", "query": "name == 'John'" }, "response": { - "documents": [ + "records": [ { "id": "1234", - "contents": { + "data": { "name": "John Doe", "age": 37, "starsign": "Leo" @@ -47,10 +44,10 @@ "query": "name == 'John' AND starsign == 'Leo'" }, "response": { - "documents": [ + "records": [ { "id": "1234", - "contents": { + "data": { "name": "John Doe", "age": 37, "starsign": "Leo" @@ -67,10 +64,10 @@ "query": "name == 'John' OR name == 'Jane'" }, "response": { - "documents": [ + "records": [ { "id": "1234", - "contents": { + "data": { "name": "John Doe", "age": 37, "starsign": "Leo" @@ -82,7 +79,7 @@ ], "delete": [ { - "title": "Delete a document", + "title": "Delete a record", "run_check": false, "request": { "id": "1234", diff --git a/search/handler/search.go b/search/handler/search.go index 38aa90b..84d457d 100644 --- a/search/handler/search.go +++ b/search/handler/search.go @@ -142,29 +142,26 @@ func (s *Search) Index(ctx context.Context, request *pb.IndexRequest, response * if !ok { return errors.Unauthorized(method, "Unauthorized") } - if request.Document == nil { - return errors.BadRequest(method, "Missing document param") + if request.Data == nil { + return errors.BadRequest(method, "Missing data") } - if len(request.Document.Id) == 0 { - request.Document.Id = uuid.New().String() + if len(request.Id) == 0 { + request.Id = uuid.New().String() } if len(request.Index) == 0 { - return errors.BadRequest(method, "Missing index param") + return errors.BadRequest(method, "Missing index") } if !isValidIndexName(request.Index) { return errors.BadRequest(method, "Index name should contain only alphanumerics and hyphens") } - if request.Document.Contents == nil { - return errors.BadRequest(method, "Missing document.contents param") - } - b, err := request.Document.Contents.MarshalJSON() + b, err := request.Data.MarshalJSON() if err != nil { return errors.BadRequest(method, "Error processing document") } req := openapi.CreateRequest{ Index: indexName(tnt, request.Index), - DocumentID: request.Document.Id, + DocumentID: request.Id, Body: bytes.NewBuffer(b), } rsp, err := req.Do(ctx, s.client) @@ -177,7 +174,11 @@ func (s *Search) Index(ctx context.Context, request *pb.IndexRequest, response * log.Errorf("Error indexing doc %s", rsp.String()) return errors.InternalServerError(method, "Error indexing document") } - response.Id = req.DocumentID + response.Record = &pb.Record{ + Id: req.DocumentID, + Data: request.Data, + } + return nil } @@ -269,9 +270,9 @@ func (s *Search) Search(ctx context.Context, request *pb.SearchRequest, response log.Errorf("Error unmarshalling doc %s", err) return errors.InternalServerError(method, "Error searching documents") } - response.Documents = append(response.Documents, &pb.Document{ - Id: v.ID, - Contents: vs, + response.Records = append(response.Records, &pb.Record{ + Id: v.ID, + Data: vs, }) } return nil diff --git a/search/proto/search.pb.go b/search/proto/search.pb.go index 9161917..14097ca 100644 --- a/search/proto/search.pb.go +++ b/search/proto/search.pb.go @@ -21,16 +21,18 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Index a document i.e. insert a document to search for. +// Index a record i.e. insert a document to search for. type IndexRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The document to index - Document *Document `protobuf:"bytes,1,opt,name=document,proto3" json:"document,omitempty"` - // The index this document belongs to - Index string `protobuf:"bytes,2,opt,name=index,proto3" json:"index,omitempty"` + // The index this record belongs to + Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` + // The data to index + Data *structpb.Struct `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + // Optional ID for the record + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` } func (x *IndexRequest) Reset() { @@ -65,13 +67,6 @@ func (*IndexRequest) Descriptor() ([]byte, []int) { return file_proto_search_proto_rawDescGZIP(), []int{0} } -func (x *IndexRequest) GetDocument() *Document { - if x != nil { - return x.Document - } - return nil -} - func (x *IndexRequest) GetIndex() string { if x != nil { return x.Index @@ -79,19 +74,33 @@ func (x *IndexRequest) GetIndex() string { return "" } -type Document struct { +func (x *IndexRequest) GetData() *structpb.Struct { + if x != nil { + return x.Data + } + return nil +} + +func (x *IndexRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type Record struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The ID for this document. If blank, one will be generated + // The ID for this record. If blank, one will be generated Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The JSON contents of the document - Contents *structpb.Struct `protobuf:"bytes,2,opt,name=contents,proto3" json:"contents,omitempty"` + // The JSON contents of the record + Data *structpb.Struct `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` } -func (x *Document) Reset() { - *x = Document{} +func (x *Record) Reset() { + *x = Record{} if protoimpl.UnsafeEnabled { mi := &file_proto_search_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -99,13 +108,13 @@ func (x *Document) Reset() { } } -func (x *Document) String() string { +func (x *Record) String() string { return protoimpl.X.MessageStringOf(x) } -func (*Document) ProtoMessage() {} +func (*Record) ProtoMessage() {} -func (x *Document) ProtoReflect() protoreflect.Message { +func (x *Record) ProtoReflect() protoreflect.Message { mi := &file_proto_search_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -117,21 +126,21 @@ func (x *Document) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use Document.ProtoReflect.Descriptor instead. -func (*Document) Descriptor() ([]byte, []int) { +// Deprecated: Use Record.ProtoReflect.Descriptor instead. +func (*Record) Descriptor() ([]byte, []int) { return file_proto_search_proto_rawDescGZIP(), []int{1} } -func (x *Document) GetId() string { +func (x *Record) GetId() string { if x != nil { return x.Id } return "" } -func (x *Document) GetContents() *structpb.Struct { +func (x *Record) GetData() *structpb.Struct { if x != nil { - return x.Contents + return x.Data } return nil } @@ -141,7 +150,8 @@ type IndexResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + // the indexed record + Record *Record `protobuf:"bytes,1,opt,name=record,proto3" json:"record,omitempty"` } func (x *IndexResponse) Reset() { @@ -176,22 +186,22 @@ func (*IndexResponse) Descriptor() ([]byte, []int) { return file_proto_search_proto_rawDescGZIP(), []int{2} } -func (x *IndexResponse) GetId() string { +func (x *IndexResponse) GetRecord() *Record { if x != nil { - return x.Id + return x.Record } - return "" + return nil } -// Delete a document given its ID +// Delete a record given its ID type DeleteRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The ID of the document to delete + // The ID of the record to delete Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // The index the document belongs to + // The index the record belongs to Index string `protobuf:"bytes,2,opt,name=index,proto3" json:"index,omitempty"` } @@ -279,13 +289,13 @@ func (*DeleteResponse) Descriptor() ([]byte, []int) { return file_proto_search_proto_rawDescGZIP(), []int{4} } -// Search for documents in a given in index +// Search for records in a given in index type SearchRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The index the document belongs to + // The index the record belongs to Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` // The query. See docs for query language examples Query string `protobuf:"bytes,2,opt,name=query,proto3" json:"query,omitempty"` @@ -342,8 +352,8 @@ type SearchResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // The matching documents - Documents []*Document `protobuf:"bytes,1,rep,name=documents,proto3" json:"documents,omitempty"` + // The matching records + Records []*Record `protobuf:"bytes,1,rep,name=records,proto3" json:"records,omitempty"` } func (x *SearchResponse) Reset() { @@ -378,9 +388,9 @@ func (*SearchResponse) Descriptor() ([]byte, []int) { return file_proto_search_proto_rawDescGZIP(), []int{6} } -func (x *SearchResponse) GetDocuments() []*Document { +func (x *SearchResponse) GetRecords() []*Record { if x != nil { - return x.Documents + return x.Records } return nil } @@ -391,7 +401,7 @@ type CreateIndexRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - // the name of the index + // The name of the index Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` } @@ -622,66 +632,67 @@ var file_proto_search_proto_rawDesc = []byte{ 0x0a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x06, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x73, 0x74, - 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x52, 0x0a, 0x0c, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x64, 0x6f, - 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x08, - 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x4f, - 0x0a, 0x08, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x33, 0x0a, 0x08, 0x63, 0x6f, - 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x73, 0x22, - 0x1f, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, - 0x22, 0x35, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, - 0x64, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x65, 0x61, - 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, + 0x72, 0x75, 0x63, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x61, 0x0a, 0x0c, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x12, 0x14, 0x0a, 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x22, 0x40, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2e, 0x0a, 0x09, 0x64, 0x6f, 0x63, 0x75, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x73, 0x65, - 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x09, 0x64, - 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x2a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x22, 0x2f, 0x0a, 0x05, 0x46, 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x12, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, - 0xca, 0x02, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x05, 0x49, 0x6e, - 0x64, 0x65, 0x78, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x61, 0x72, - 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x39, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x73, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, - 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, - 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x45, 0x0a, + 0x06, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x2b, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x52, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x37, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x26, 0x0a, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x52, + 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x06, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x22, 0x35, 0x0a, + 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, + 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x14, + 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x22, 0x10, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x0a, + 0x05, 0x71, 0x75, 0x65, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x71, 0x75, + 0x65, 0x72, 0x79, 0x22, 0x3a, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, + 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x52, 0x07, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x73, 0x22, + 0x2a, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x2f, 0x0a, 0x05, 0x46, + 0x69, 0x65, 0x6c, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0x15, 0x0a, 0x13, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x2a, 0x0a, 0x12, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, + 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, + 0x15, 0x0a, 0x13, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xca, 0x02, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x12, 0x36, 0x0a, 0x05, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x14, 0x2e, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x15, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x06, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x15, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x43, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, - 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, - 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, - 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x53, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, + 0x48, 0x0a, 0x0b, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1a, + 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x61, + 0x72, 0x63, 0x68, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x48, 0x0a, 0x0b, 0x44, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1a, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x42, 0x10, 0x5a, 0x0e, 0x2e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x3b, 0x73, + 0x65, 0x61, 0x72, 0x63, 0x68, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -699,7 +710,7 @@ func file_proto_search_proto_rawDescGZIP() []byte { var file_proto_search_proto_msgTypes = make([]protoimpl.MessageInfo, 12) var file_proto_search_proto_goTypes = []interface{}{ (*IndexRequest)(nil), // 0: search.IndexRequest - (*Document)(nil), // 1: search.Document + (*Record)(nil), // 1: search.Record (*IndexResponse)(nil), // 2: search.IndexResponse (*DeleteRequest)(nil), // 3: search.DeleteRequest (*DeleteResponse)(nil), // 4: search.DeleteResponse @@ -713,24 +724,25 @@ var file_proto_search_proto_goTypes = []interface{}{ (*structpb.Struct)(nil), // 12: google.protobuf.Struct } var file_proto_search_proto_depIdxs = []int32{ - 1, // 0: search.IndexRequest.document:type_name -> search.Document - 12, // 1: search.Document.contents:type_name -> google.protobuf.Struct - 1, // 2: search.SearchResponse.documents:type_name -> search.Document - 0, // 3: search.Search.Index:input_type -> search.IndexRequest - 3, // 4: search.Search.Delete:input_type -> search.DeleteRequest - 5, // 5: search.Search.Search:input_type -> search.SearchRequest - 7, // 6: search.Search.CreateIndex:input_type -> search.CreateIndexRequest - 10, // 7: search.Search.DeleteIndex:input_type -> search.DeleteIndexRequest - 2, // 8: search.Search.Index:output_type -> search.IndexResponse - 4, // 9: search.Search.Delete:output_type -> search.DeleteResponse - 6, // 10: search.Search.Search:output_type -> search.SearchResponse - 9, // 11: search.Search.CreateIndex:output_type -> search.CreateIndexResponse - 11, // 12: search.Search.DeleteIndex:output_type -> search.DeleteIndexResponse - 8, // [8:13] is the sub-list for method output_type - 3, // [3:8] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name + 12, // 0: search.IndexRequest.data:type_name -> google.protobuf.Struct + 12, // 1: search.Record.data:type_name -> google.protobuf.Struct + 1, // 2: search.IndexResponse.record:type_name -> search.Record + 1, // 3: search.SearchResponse.records:type_name -> search.Record + 0, // 4: search.Search.Index:input_type -> search.IndexRequest + 3, // 5: search.Search.Delete:input_type -> search.DeleteRequest + 5, // 6: search.Search.Search:input_type -> search.SearchRequest + 7, // 7: search.Search.CreateIndex:input_type -> search.CreateIndexRequest + 10, // 8: search.Search.DeleteIndex:input_type -> search.DeleteIndexRequest + 2, // 9: search.Search.Index:output_type -> search.IndexResponse + 4, // 10: search.Search.Delete:output_type -> search.DeleteResponse + 6, // 11: search.Search.Search:output_type -> search.SearchResponse + 9, // 12: search.Search.CreateIndex:output_type -> search.CreateIndexResponse + 11, // 13: search.Search.DeleteIndex:output_type -> search.DeleteIndexResponse + 9, // [9:14] is the sub-list for method output_type + 4, // [4:9] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_proto_search_proto_init() } @@ -752,7 +764,7 @@ func file_proto_search_proto_init() { } } file_proto_search_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Document); i { + switch v := v.(*Record); i { case 0: return &v.state case 1: diff --git a/search/proto/search.proto b/search/proto/search.proto index 0e49a60..63fa72d 100644 --- a/search/proto/search.proto +++ b/search/proto/search.proto @@ -14,39 +14,41 @@ service Search { rpc DeleteIndex(DeleteIndexRequest) returns (DeleteIndexResponse) {} } -// Index a document i.e. insert a document to search for. +// Index a record i.e. insert a document to search for. message IndexRequest { - // The document to index - Document document = 1; - // The index this document belongs to - string index = 2; - + // The index this record belongs to + string index = 1; + // The data to index + google.protobuf.Struct data = 2; + // Optional ID for the record + string id = 3; } -message Document { - // The ID for this document. If blank, one will be generated +message Record { + // The ID for this record. If blank, one will be generated string id = 1; - // The JSON contents of the document - google.protobuf.Struct contents = 2; + // The JSON contents of the record + google.protobuf.Struct data = 2; } message IndexResponse { - string id = 1; + // the indexed record + Record record = 1; } -// Delete a document given its ID +// Delete a record given its ID message DeleteRequest { - // The ID of the document to delete + // The ID of the record to delete string id = 1; - // The index the document belongs to + // The index the record belongs to string index = 2; } message DeleteResponse {} -// Search for documents in a given in index +// Search for records in a given in index message SearchRequest { - // The index the document belongs to + // The index the record belongs to string index = 1; // The query. See docs for query language examples @@ -54,8 +56,8 @@ message SearchRequest { } message SearchResponse { - // The matching documents - repeated Document documents = 1; + // The matching records + repeated Record records = 1; }