package search // Settings // Mapping configures an index in OpenSearch type Settings struct { Index *SettingsIndex `json:"index,omitempty"` } type SettingsIndex struct { NumberOfShards int `json:"number_of_shards,omitempty"` NumberOfReplicas int `json:"number_of_replicas,omitempty"` } type Mappings struct { Properties map[string]MappingProperty `json:"properties,omitempty"` } type MappingProperty struct { Type string `json:"type,omitempty"` // empty for sub-structs described with properties Enabled bool `json:"enabled,omitempty"` Fields map[string]MappingFieldProperties `json:"fields,omitempty"` Properties map[string]MappingProperty `json:"properties,omitempty"` } type MappingFieldProperties struct { Keyword *MappingKeyword `json:"keyword"` } type MappingKeyword struct { Type string `json:"type"` // ="keyword" IgnoreAbove int `json:"ignore_above"` // e.g. 256 } type SearchRequestBody struct { Sort []map[string]string `json:"sort,omitempty"` // order and order_by Size int64 `json:"size,omitempty"` // limit From int64 `json:"from,omitempty"` // offset Query Query `json:"query"` Timeout string `json:"timeout,omitempty"` // timeout for search } // Query NOTE: We are only using bool filter queries, to be able to always do the correct sorting, not based on the relevancy score // https://opensearch.org/docs/latest/opensearch/query-dsl/bool/ type Query struct { Bool *QueryBool `json:"bool,omitempty"` } type QueryBool struct { Filter []FilterQuery `json:"filter,omitempty"` // List of things that must appear in matching documents. However, unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching MustNot []FilterQuery `json:"must_not,omitempty"` // List of things that must not appear in the matching documents. Clauses are executed in filter context meaning that scoring is ignored and clauses are considered for caching. Because scoring is ignored, a score of 0 for all documents is returned } type FilterQuery struct { // one of: Match *QueryMatch `json:"match,omitempty"` Term *QueryTerm `json:"term,omitempty"` Range *QueryRange `json:"range,omitempty"` MultiMatch *QueryMultiMatch `json:"multi_match,omitempty"` Bool *QueryBool `json:"bool,omitempty"` QueryString *QueryString `json:"query_string,omitempty"` Wildcard *QueryWildcard `json:"wildcard,omitempty"` // https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html } type QueryMatch map[string]string type QueryTerm map[string]string type QueryWildcard map[string]string type QueryMultiMatch struct { Query string `json:"query"` // Full value match search in selected fields Fields []string `json:"fields,omitempty" doc:"List of fields"` Type QueryMultiMatchType `json:"type,omitempty"` } type QueryMultiMatchType string const ( QueryMultiMatchTypePhrase QueryMultiMatchType = "phrase" ) type QueryString struct { Query string `json:"query"` // Text search with partial matches, using asterisk for optional or question mark for required wildcards before and/or after text Fields []string `json:"fields,omitempty" doc:"List of fields"` } type QueryRange map[string]QueryExpr type QueryExpr map[string]string // SearchResponseBody example: // { // "took":872, // "timed_out":false, // "_shards":{ // "total":38, // "successful":38, // "skipped":0, // "failed":0 // }, // "hits":{ // "total":{ // "value":0, // "relation":"eq" // }, // "max_score":null, // "hits":[ // { // "_index": "go-utils-audit-test-20211030", // "_type": "_doc", // "_id": "Tj9l5XwBWRiAneoYazic", // "_score": 1.2039728, // "_source": { // "@timestamp": "2021-10-30T15:03:20.679481+02:00", // "@end_time": "2021-10-30T15:03:20.469481+02:00", // "@duration_ms": -210, // "test1": "6", // "test2": "ACC_00098", // "test3": 10, // "http": { // "method": "GET", // "path": "/accounts" // }, // "http_method": "GET", // "http_path": "/accounts" // } // }, // ] // } // } type SearchResponseBody struct { Took int `json:"took"` // milliseconds TimedOut bool `json:"timed_out"` Shards SearchResponseShards `json:"_shards"` Hits SearchResponseHits `json:"hits"` } type SearchResponseShards struct { Total int `json:"total"` Successful int `json:"successful"` Skipped int `json:"skipped"` Failed int `json:"failed"` } type SearchResponseHits struct { Total SearchResponseHitsTotal `json:"total"` MaxScore *float64 `json:"max_score,omitempty"` Hits []HitDoc `json:"hits"` } type SearchResponseHitsTotal struct { Value int `json:"value"` // e.g. 0 when no docs matched Relation string `json:"relation"` // e.g. "eq" } type HitDoc struct { Index string `json:"_index"` // name of index Type string `json:"_type"` // _doc ID string `json:"_id"` Score float64 `json:"_score"` // Source map[string]interface{} `json:"_source"` // the document of itemType } // GetResponseBody Example: // { // "_index": "go-utils-search-docs-test", // "_type": "_doc", // "_id": "836c6443-5b0e-489b-aa0f-712ebed96841", // "_version": 1, // "_seq_no": 6, // "_primary_term": 1, // "found": true, // "_source": { ... } // } type GetResponseBody struct { Index string `json:"_index"` // name of index Type string `json:"_type"` // _doc ID string `json:"_id"` Version int `json:"_version"` SeqNo int `json:"_seq_no"` PrimaryTerm int `json:"_primary_term"` Found bool `json:"found"` Source map[string]interface{} `json:"_source"` // the document of itemType }