Search returns results matching a query, paginated by after.
(query string, after ...string)
| 129 | |
| 130 | // Search returns results matching a query, paginated by after. |
| 131 | func (s *Store) Search(query string, after ...string) (*SearchResults, error) { |
| 132 | var results SearchResults |
| 133 | |
| 134 | res, err := s.es.Search( |
| 135 | s.es.Search.WithIndex(s.indexName), |
| 136 | s.es.Search.WithBody(s.buildQuery(query, after...)), |
| 137 | ) |
| 138 | if err != nil { |
| 139 | return &results, err |
| 140 | } |
| 141 | defer res.Body.Close() |
| 142 | |
| 143 | if res.IsError() { |
| 144 | var e map[string]interface{} |
| 145 | if err := json.NewDecoder(res.Body).Decode(&e); err != nil { |
| 146 | return &results, err |
| 147 | } |
| 148 | return &results, fmt.Errorf("[%s] %s: %s", res.Status(), e["error"].(map[string]interface{})["type"], e["error"].(map[string]interface{})["reason"]) |
| 149 | } |
| 150 | |
| 151 | type envelopeResponse struct { |
| 152 | Took int |
| 153 | Hits struct { |
| 154 | Total struct { |
| 155 | Value int |
| 156 | } |
| 157 | Hits []struct { |
| 158 | ID string `json:"_id"` |
| 159 | Source json.RawMessage `json:"_source"` |
| 160 | Highlights json.RawMessage `json:"highlight"` |
| 161 | Sort []interface{} `json:"sort"` |
| 162 | } |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | var r envelopeResponse |
| 167 | if err := json.NewDecoder(res.Body).Decode(&r); err != nil { |
| 168 | return &results, err |
| 169 | } |
| 170 | |
| 171 | results.Total = r.Hits.Total.Value |
| 172 | |
| 173 | if len(r.Hits.Hits) < 1 { |
| 174 | results.Hits = []*Hit{} |
| 175 | return &results, nil |
| 176 | } |
| 177 | |
| 178 | for _, hit := range r.Hits.Hits { |
| 179 | var h Hit |
| 180 | h.ID = hit.ID |
| 181 | h.Sort = hit.Sort |
| 182 | h.URL = strings.Join([]string{baseURL, h.ID, ""}, "/") |
| 183 | |
| 184 | if err := json.Unmarshal(hit.Source, &h); err != nil { |
| 185 | return &results, err |
| 186 | } |
| 187 | |
| 188 | if len(hit.Highlights) > 0 { |