# Elastic Elastic is an [Elasticsearch](http://www.elasticsearch.org/) client for the [Go](http://www.golang.org/) programming language. [![Build Status](https://travis-ci.org/olivere/elastic.svg?branch=master)](https://travis-ci.org/olivere/elastic) [![Godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/olivere/elastic) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/olivere/elastic/master/LICENSE) See the [wiki](https://github.com/olivere/elastic/wiki) for additional information about Elastic. ## Releases ### Current version This is the source code of the current version of Elastic (version 2). ### Earlier versions If you came from an earlier version and found that you cannot update, don't worry. Earlier versions are still available. All you need to do is go-get them and change your import path. See below for details. Here's what you need to do to use Elastic version 1: ```sh $ go get gopkg.in/olivere/elastic.v1 ``` Then change your import path: ```go import "gopkg.in/olivere/elastic.v1" ``` ## Status We use Elastic in production since 2012. Although Elastic is quite stable from our experience, we don't have a stable API yet. The reason for this is that Elasticsearch changes quite often and at a fast pace. At this moment we focus on features, not on a stable API. Having said that, there have been no big API changes that required you to rewrite your application big time. More often than not it's renaming APIs and adding/removing features so that we are in sync with the Elasticsearch API. Elastic supports and has been tested in production with the following Elasticsearch versions: 0.90, 1.0, 1.1, 1.2, 1.3, and 1.4. Elasticsearch has quite a few features. A lot of them are not yet implemented in Elastic (see below for details). I add features and APIs as required. It's straightforward to implement missing pieces. I'm accepting pull requests :-) Having said that, I hope you find the project useful. ## Usage The first thing you do is to create a Client. The client connects to Elasticsearch on http://127.0.0.1:9200 by default. You typically create one client for your app. Here's a complete example. ```go // Create a client client, err := elastic.NewClient() if err != nil { // Handle error } // Create an index _, err = client.CreateIndex("twitter").Do() if err != nil { // Handle error panic(err) } // Add a document to the index tweet := Tweet{User: "olivere", Message: "Take Five"} _, err = client.Index(). Index("twitter"). Type("tweet"). Id("1"). BodyJson(tweet). Do() if err != nil { // Handle error panic(err) } // Search with a term query termQuery := elastic.NewTermQuery("user", "olivere") searchResult, err := client.Search(). Index("twitter"). // search in index "twitter" Query(&termQuery). // specify the query Sort("user", true). // sort by "user" field, ascending From(0).Size(10). // take documents 0-9 Debug(true). // print request and response to stdout Pretty(true). // pretty print request and response JSON Do() // execute if err != nil { // Handle error panic(err) } // searchResult is of type SearchResult and returns hits, suggestions, // and all kinds of other information from Elasticsearch. fmt.Printf("Query took %d milliseconds\n", searchResult.TookInMillis) // Each is a convenience function that iterates over hits in a search result. // It makes sure you don't need to check for nil values in the response. // However, it ignores errors in serialization. If you want full control // over iterating the hits, see below. var ttyp Tweet for _, item := range searchResult.Each(reflect.TypeOf(ttyp)) { t := item.(Tweet) fmt.Printf("Tweet by %s: %s\n", t.User, t.Message) } // TotalHits is another convenience function that works even when something goes wrong. fmt.Printf("Found a total of %d tweets\n", searchResult.TotalHits()) // Here's how you iterate through results with full control over each step. if searchResult.Hits != nil { fmt.Printf("Found a total of %d tweets\n", searchResult.Hits.TotalHits) // Iterate through results for _, hit := range searchResult.Hits.Hits { // hit.Index contains the name of the index // Deserialize hit.Source into a Tweet (could also be just a map[string]interface{}). var t Tweet err := json.Unmarshal(*hit.Source, &t) if err != nil { // Deserialization failed } // Work with tweet fmt.Printf("Tweet by %s: %s\n", t.User, t.Message) } } else { // No hits fmt.Print("Found no tweets\n") } // Delete the index again _, err = client.DeleteIndex("twitter").Do() if err != nil { // Handle error panic(err) } ``` See the [wiki](https://github.com/olivere/elastic/wiki) for more details. ## API Status Here's the current API status. ### APIs - [x] Search (most queries, filters, facets, aggregations etc. are implemented: see below) - [x] Index - [x] Get - [x] Delete - [x] Delete By Query - [x] Update - [x] Multi Get - [x] Bulk - [ ] Bulk UDP - [ ] Term vectors - [ ] Multi term vectors - [x] Count - [ ] Validate - [x] Explain - [x] Search - [ ] Search shards - [x] Search template - [x] Facets (most are implemented, see below) - [x] Aggregates (most are implemented, see below) - [x] Multi Search - [x] Percolate - [ ] More like this - [ ] Benchmark ### Indices - [x] Create index - [x] Delete index - [x] Get index - [x] Indices exists - [x] Open/close index - [x] Put mapping - [x] Get mapping - [ ] Get field mapping - [x] Types exist - [x] Delete mapping - [x] Index aliases - [ ] Update indices settings - [x] Get settings - [ ] Analyze - [x] Index templates - [ ] Warmers - [ ] Status - [x] Indices stats - [ ] Indices segments - [ ] Indices recovery - [ ] Clear cache - [x] Flush - [x] Refresh - [x] Optimize - [ ] Upgrade ### Snapshot and Restore - [ ] Snapshot - [ ] Restore - [ ] Snapshot status - [ ] Monitoring snapshot/restore progress - [ ] Partial restore ### Cat APIs Not implemented. Those are better suited for operating with Elasticsearch on the command line. ### Cluster - [x] Health - [x] State - [ ] Stats - [ ] Pending cluster tasks - [ ] Cluster reroute - [ ] Cluster update settings - [ ] Nodes stats - [x] Nodes info - [ ] Nodes hot_threads - [ ] Nodes shutdown ### Query DSL #### Queries - [x] `match` - [x] `multi_match` - [x] `bool` - [x] `boosting` - [ ] `common_terms` - [ ] `constant_score` - [x] `dis_max` - [x] `filtered` - [x] `fuzzy_like_this_query` (`flt`) - [x] `fuzzy_like_this_field_query` (`flt_field`) - [x] `function_score` - [x] `fuzzy` - [ ] `geo_shape` - [x] `has_child` - [x] `has_parent` - [x] `ids` - [ ] `indices` - [x] `match_all` - [x] `mlt` - [x] `mlt_field` - [x] `nested` - [x] `prefix` - [x] `query_string` - [x] `simple_query_string` - [x] `range` - [x] `regexp` - [ ] `span_first` - [ ] `span_multi_term` - [ ] `span_near` - [ ] `span_not` - [ ] `span_or` - [ ] `span_term` - [x] `term` - [x] `terms` - [ ] `top_children` - [x] `wildcard` - [ ] `minimum_should_match` - [ ] `multi_term_query_rewrite` - [x] `template_query` #### Filters - [x] `and` - [x] `bool` - [x] `exists` - [ ] `geo_bounding_box` - [x] `geo_distance` - [ ] `geo_distance_range` - [x] `geo_polygon` - [ ] `geoshape` - [ ] `geohash` - [x] `has_child` - [x] `has_parent` - [x] `ids` - [ ] `indices` - [x] `limit` - [x] `match_all` - [x] `missing` - [x] `nested` - [x] `not` - [x] `or` - [x] `prefix` - [x] `query` - [x] `range` - [x] `regexp` - [ ] `script` - [x] `term` - [x] `terms` - [x] `type` ### Facets - [x] Terms - [x] Range - [x] Histogram - [x] Date Histogram - [x] Filter - [x] Query - [x] Statistical - [x] Terms Stats - [x] Geo Distance ### Aggregations - [x] min - [x] max - [x] sum - [x] avg - [x] stats - [x] extended stats - [x] value count - [x] percentiles - [x] percentile ranks - [x] cardinality - [x] geo bounds - [x] top hits - [ ] scripted metric - [x] global - [x] filter - [x] filters - [x] missing - [x] nested - [x] reverse nested - [x] children - [x] terms - [x] significant terms - [x] range - [x] date range - [x] ipv4 range - [x] histogram - [x] date histogram - [x] geo distance - [x] geohash grid ### Sorting - [x] Sort by score - [x] Sort by field - [x] Sort by geo distance - [x] Sort by script ### Scan Scrolling through documents (e.g. `search_type=scan`) are implemented via the `Scroll` and `Scan` services. The `ClearScroll` API is implemented as well. ## How to contribute Read [the contribution guidelines](https://github.com/olivere/elastic/blob/master/CONTRIBUTING.md). ## Credits Thanks a lot for the great folks working hard on [Elasticsearch](http://www.elasticsearch.org/) and [Go](http://www.golang.org/). ## LICENSE MIT-LICENSE. See [LICENSE](http://olivere.mit-license.org/) or the LICENSE file provided in the repository for details.