Skip to content
Official Elasticsearch Rust Client
Rust Other
  1. Rust 99.0%
  2. Other 1.0%
Branch: master
Clone or download
russcam Add CONTRIBUTING.md
This commit splits the information in README.md that relates to contributing, out into
a separate CONTRIBUTING.md file.
Add link to docs in README
Latest commit bc05305 Jan 23, 2020

README.md

Official Rust Client for Elasticsearch.

Full documentation is available at https://docs.rs/elasticsearch

The project is still very much a work in progress and in an alpha state; input and contributions welcome!

Versions and Compatibility

Rust client Elasticsearch Status
7.x 7.x alpha

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.

Getting started

The client exposes all Elasticsearch APIs as associated functions, either on the root client, Elasticsearch, or on one of the namespaced clients, such as Cat, Indices, etc. The namespaced clients are based on the grouping of APIs within the Elasticsearch and X-Pack REST API specs from which much of the client is generated. All API functions are async only, and can be awaited.

Installing

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

[dependencies]
elasticsearch = "7.5.2-alpha1"

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

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

Create a client

Build a transport to make API requests to Elasticsearch using the TransportBuilder, which allows setting of proxies and authentication schemes

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

use elasticsearch::{Error, Elasticsearch};

fn run() {
    let client = Elasticsearch::default();
}

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

use elasticsearch::{
    Error, Elasticsearch, 
    http::transport::{Transport, SingleNodeConnectionPool}
};

fn run() -> Result<(), Error> {
    let transport = Transport::single_node("https://example.com")?;
    let client = Elasticsearch::new(transport);
    Ok(())
}

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

use elasticsearch::{
    auth::Credentials,
    Error, Elasticsearch, 
    http::transport::Transport,
};
use url::Url;

fn run() -> Result<(), Error> {
    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);
    Ok(())
}

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]

use elasticsearch::{
    auth::Credentials,
    Error, Elasticsearch, 
    http::transport::{TransportBuilder,SingleNodeConnectionPool},
};
use url::Url;

fn run() -> Result<(), Error> {
    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);
    Ok(())
}

Making API calls

The following will execute a POST request to /_search?allow_no_indices=true with a JSON body of {"query":{"match_all":{}}}

use elasticsearch::{Elasticsearch, Error, SearchParts};
use serde_json::{json, Value};

async fn run() -> Result<(), Error> {

    let client = Elasticsearch::default();
    
    // make a search API call
    let search_response = client
        .search(SearchParts::None)
        .body(json!({
            "query": {
                "match_all": {}
            }
        }))
        .allow_no_indices(true)
        .send()
        .await?;
    
    // get the HTTP response status code
    let status_code = search_response.status_code();
    
    // read the response body. Consumes search_response
    let response_body = search_response.read_body::<Value>().await?; 
    
    // read fields from the response body         
    let took = response_body["took"].as_i64().unwrap();

    Ok(())
}

The client provides functions on each API builder struct for all query string parameters available for that API. APIs with multiple URI path variants, where some can contain parts parameters, are modelled as enums.

Elasticsearch also has an async send function on the root that allows sending an API call to an endpoint not represented as an API function, for example, experimental and beta APIs

use elasticsearch::{http::Method, Elasticsearch, Error, SearchParts};
use http::HeaderMap;
use serde_json::{json, Value};
use url::Url;

async fn run() -> Result<(), Error> {
    let client = Elasticsearch::default();
    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())
        )
        .await?;
    Ok(())
}

License

This is free software, licensed under The Apache License Version 2.0..

You can’t perform that action at this time.