update search api

This commit is contained in:
Asim Aslam
2022-02-21 13:08:32 +00:00
parent 8adc4da930
commit 8fd2f2bc19
6 changed files with 262 additions and 174 deletions

View File

@@ -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'

79
search/architecture.md Normal file
View File

@@ -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
```

View File

@@ -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",

View File

@@ -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

View File

@@ -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:

View File

@@ -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;
}