Crate elasticsearch

source ·
Expand description

Official Rust client for Elasticsearch

Elasticsearch is an official Rust client for Elasticsearch, providing an efficient asynchronous client for all stable Elasticsearch APIs that’s easy to use.

Versions and Compatibility

Rust clientElasticsearch
7.x7.x

A major version of the client is compatible with the same major version of Elasticsearch. Since Elasticsearch is developed following Semantic Versioning principles, Any minor/patch version of the client can be used against any minor/patch version of Elasticsearch within the same major version lineage. For example,

  • A 7.5.0 client can be used against 7.0.0 Elasticsearch
  • A 7.4.0 client can be used against 7.5.1 Elasticsearch

In the former case, a 7.5.0 client may contain additional API functions that are not available in 7.0.0 Elasticsearch. In this case, these APIs cannot be used, but for any APIs available in Elasticsearch, the respective API functions on the client will be compatible.

In the latter case, a 7.4.0 client won’t contain API functions for APIs that are introduced in Elasticsearch 7.5.0+, but for all other APIs available in Elasticsearch, the respective API functions on the client will be compatible.

No compatibility assurances are given between different major versions of the client and Elasticsearch. Major differences likely exist between major versions of Elasticsearch, particularly around request and response object formats, but also around API urls and behaviour.

Features

The following are a list of Cargo features that can be enabled or disabled:

  • native-tls (enabled by default): Enables TLS functionality provided by native-tls.
  • rustls-tls: Enables TLS functionality provided by rustls.
  • beta-apis: Enables beta APIs. Beta APIs are on track to become stable and permanent features. Use them with caution because it is possible that breaking changes are made to these APIs in a minor version.
  • experimental-apis: Enables experimental APIs. Experimental APIs are just that - an experiment. An experimental API might have breaking changes in any future version, or it might even be removed entirely. This feature also enables beta-apis.

Getting started

Add the elasticsearch crate and version to Cargo.toml. Choose the version that is compatible with the version of Elasticsearch you’re using

[dependencies]
elasticsearch = "8.5.0-alpha.1"

The following optional dependencies may also be useful to create requests and read responses

serde = "~1"
serde_json = "~1"

Async support with tokio

The client uses reqwest to make HTTP calls, which internally uses the tokio runtime for async support. As such, you may require to take a dependency on tokio in order to use the client. For example, in Cargo.toml, you may need the following dependency

tokio = { version = "*", features = ["full"] }

and to attribute async main function with #[tokio::main]

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // your code ...
    Ok(())
}

and attribute test functions with #[tokio::test]

#[tokio::test]
async fn my_test() -> Result<(), Box<dyn std::error::Error>> {
    // your code ...
    Ok(())
}

Create a client

To create a client to make API calls to Elasticsearch running on http://localhost:9200

let client = Elasticsearch::default();

Alternatively, you can create a client to make API calls against Elasticsearch running on a specific url::Url

let transport = Transport::single_node("https://example.com")?;
let client = Elasticsearch::new(transport);

If you’re running against an Elasticsearch deployment in Elastic Cloud, a client can be created using a Cloud ID and credentials retrieved from the Cloud web console

let cloud_id = "cluster_name:Y2xvdWQtZW5kcG9pbnQuZXhhbXBsZSQzZGFkZjgyM2YwNTM4ODQ5N2VhNjg0MjM2ZDkxOGExYQ==";
let credentials = Credentials::Basic("<username>".into(), "<password>".into());
let transport = Transport::cloud(cloud_id, credentials)?;
let client = Elasticsearch::new(transport);

More control over how a Transport is built can be achieved using TransportBuilder to build a transport, and passing it to Elasticsearch::new create a new instance of Elasticsearch

let url = Url::parse("https://example.com")?;
let conn_pool = SingleNodeConnectionPool::new(url);
let transport = TransportBuilder::new(conn_pool).disable_proxy().build()?;
let client = Elasticsearch::new(transport);

Making API calls

The client exposes all stable Elasticsearch APIs, either on the root Elasticsearch client, or on a namespace client that groups related APIs, such as Cat, which groups the Cat related APIs. All API functions are async and can be awaited.

The following makes an API call to the cat indices API

let response = client
    .cat()
    .indices(CatIndicesParts::Index(&["*"]))
    .send()
    .await?;

let response_body = response.json::<Value>().await?;
for record in response_body.as_array().unwrap() {
    // print the name of each index
    println!("{}", record["index"].as_str().unwrap());
}

For APIs that contain parts of the Url path to be provided by the consumer, the Url path variants are modelled as an enum, such as CatIndicesParts in the above example, which models the variants of the CatIndices API.

Indexing

Indexing a single document can be achieved with the index API

let response = client
    .index(IndexParts::IndexId("tweets", "1"))
    .body(json!({
        "id": 1,
        "user": "kimchy",
        "post_date": "2009-11-15T00:00:00Z",
        "message": "Trying out Elasticsearch, so far so good?"
    }))
    .send()
    .await?;

let successful = response.status_code().is_success();

For indexing multiple documents, the bulk API is a better option, allowing multiple operations to be sent in one API call

let mut body: Vec<JsonBody<_>> = Vec::with_capacity(4);

// add the first operation and document
body.push(json!({"index": {"_id": "1"}}).into());
body.push(json!({
    "id": 1,
    "user": "kimchy",
    "post_date": "2009-11-15T00:00:00Z",
    "message": "Trying out Elasticsearch, so far so good?"
}).into());

// add the second operation and document
body.push(json!({"index": {"_id": "2"}}).into());
body.push(json!({
    "id": 2,
    "user": "forloop",
    "post_date": "2020-01-08T00:00:00Z",
    "message": "Bulk indexing with the rust client, yeah!"
}).into());

let response = client
    .bulk(BulkParts::Index("tweets"))
    .body(body)
    .send()
    .await?;

let response_body = response.json::<Value>().await?;
let successful = response_body["errors"].as_bool().unwrap() == false;

Searching

The following makes an API call to tweets/_search with the json body {"query":{"match":{"message":"Elasticsearch"}}}

let response = client
    .search(SearchParts::Index(&["tweets"]))
    .from(0)
    .size(10)
    .body(json!({
        "query": {
            "match": {
                "message": "Elasticsearch rust"
            }
        }
    }))
    .send()
    .await?;

let response_body = response.json::<Value>().await?;
let took = response_body["took"].as_i64().unwrap();
for hit in response_body["hits"]["hits"].as_array().unwrap() {
    // print the source document
    println!("{:?}", hit["_source"]);
}

Request bodies

For APIs that expect JSON, the body associated function of the API constrains the input to a type that implements serde::Serialize trait. An example of this was the indexing a single document example above.

Some APIs expect newline delimited JSON (NDJSON) however, so the body associated for these APIs constrain the input to a vector of types that implement Body trait. An example of this was the bulk indexing multiple documents above.

The Body trait represents the body of an API call, allowing for different body implementations. As well as those to represent JSON and NDJSON, a few other types also have implementations for Body, such as byte slice. Whilst these can’t be passed to the API functions directly, Elasticsearch::send can be used

let body = b"{\"query\":{\"match_all\":{}}}";

let response = client
    .send(Method::Post,
        SearchParts::Index(&["tweets"]).url().as_ref(),
        HeaderMap::new(),
        Option::<&Value>::None,
        Some(body.as_ref()),
        None,
    )
    .await?;

Re-exports

pub use crate::http::transport::DEFAULT_ADDRESS;

Modules

Async Search APIs
Authentication components
Autoscaling APIs
Cat APIs
Cross-cluster Replication APIs
Certificate components
Cluster APIs
Dangling Index APIs
Enrich APIs
EQL APIs
Features APIs
The Fleet APIs support the use of Elasticsearch as a data store for internal agent and action data. These APIs are experimental and for internal use by Fleet only.
Graph APIs
HTTP components
Index Lifecycle Management APIs
Index APIs
Ingest APIs
Licensing APIs
Logstash APIs
Migration APIs
Machine Learning APIs
Monitoring APIs
Node APIs
API parameters
Rollup APIs
Searchable snapshot APIs
Security APIs
The shutdown APIs allows preparing nodes for temporary or permanent shutdown, monitor the shutdown status, and enable a previously shut-down node to resume normal operations.
Snapshot Lifecycle Management APIs
Snapshot APIs
SQL APIs
SSL APIs
Task Management APIs
Text structure APIs
Transform APIs
Watcher (Alerting) APIs
X-Pack APIs

Structs

Builder for the Bulk API
Bulk create operation
Bulk delete operation
Bulk index operation
A bulk operation consists of a header that indicates the bulk action and the related metadata for the action, and an optional source document.
A collection of bulk operations.
Bulk update operation
Builder for the Count API
Builder for the Create API
Builder for the Delete API
Root client for top level APIs
An error with the client.
Builder for the Exists API
Builder for the Explain API
Builder for the Field Caps API
Builder for the Get API
Builder for the Get Script API
Builder for the Get Source API
Builder for the Index API
Builder for the Info API
Builder for the Knn Search API
Builder for the Mget API
Builder for the Msearch API
Builder for the Ping API
Builder for the Put Script API
Builder for the Rank Eval API
Builder for the Reindex API
Builder for the Scroll API
Builder for the Search API
Builder for the Search Mvt API
Builder for the Terms Enum API
Builder for the Update API

Enums

API parts for the Bulk API
API parts for the Clear Scroll API
API parts for the Close Point In Time API
API parts for the Count API
API parts for the Create API
API parts for the Delete By Query API
API parts for the Delete By Query Rethrottle API
API parts for the Delete API
API parts for the Delete Script API
API parts for the Exists API
API parts for the Exists Source API
API parts for the Explain API
API parts for the Field Caps API
API parts for the Get API
API parts for the Get Script Context API
API parts for the Get Script Languages API
API parts for the Get Script API
API parts for the Get Source API
API parts for the Index API
API parts for the Info API
API parts for the Knn Search API
API parts for the Mget API
API parts for the Msearch API
API parts for the Msearch Template API
API parts for the Mtermvectors API
API parts for the Open Point In Time API
API parts for the Ping API
API parts for the Put Script API
API parts for the Rank Eval API
API parts for the Reindex API
API parts for the Reindex Rethrottle API
API parts for the Render Search Template API
API parts for the Scripts Painless Execute API
API parts for the Scroll API
API parts for the Search Mvt API
API parts for the Search API
API parts for the Search Shards API
API parts for the Search Template API
API parts for the Terms Enum API
API parts for the Termvectors API
API parts for the Update By Query API
API parts for the Update By Query Rethrottle API
API parts for the Update API