Crate opensearch

Source
Expand description

Official Rust client for OpenSearch

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

§Versions and Compatibility

Rust clientOpenSearch
1.x1.x
2.x2.x, 1.x^
  • ^: With the exception of some previously deprecated APIs

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

  • A 1.5.0 client can be used against 1.0.0 OpenSearch
  • A 1.4.0 client can be used against 1.5.1 OpenSearch

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

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

In some instances, a new major version of OpenSearch may remain compatible with an older major version of the client, which may not warrant a need to update the client. Please consult COMPATIBILITY.md for more details.

No compatibility assurances are given between different major versions of the client and OpenSearch. Major differences likely exist between major versions of OpenSearch, 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.
  • aws-auth: Enables authentication with Amazon OpenSearch and OpenSearch Serverless. Performs AWS SigV4 signing using credential types from aws-types.

§Getting started

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

[dependencies]
opensearch = "1.0.0"

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 OpenSearch running on http://localhost:9200

let client = OpenSearch::default();

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

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

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

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

§Making API calls

The client exposes all stable OpenSearch APIs, either on the root OpenSearch 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 OpenSearch, 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 OpenSearch, 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":"OpenSearch"}}}

let response = client
    .search(SearchParts::Index(&["tweets"]))
    .from(0)
    .size(10)
    .body(json!({
        "query": {
            "match": {
                "message": "OpenSearch 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, OpenSearch::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?;

§Amazon OpenSearch and OpenSearch Serverless

For authenticating against an Amazon OpenSearch or OpenSearch Serverless endpoint using AWS SigV4 request signing, you must enable the aws-auth feature, then pass the AWS credentials to the TransportBuilder. The easiest way to retrieve AWS credentials in the required format is to use aws-config.

[dependencies]
opensearch = { version = "1", features = ["aws-auth"] }
aws-config = "0.10"
let creds = aws_config::load_from_env().await;
let url = Url::parse("https://...")?;
let region_provider = RegionProviderChain::default_provider().or_else("us-east-1");
let aws_config = aws_config::from_env().region(region_provider).load().await.clone();
let conn_pool = SingleNodeConnectionPool::new(url);
let transport = TransportBuilder::new(conn_pool)
    .auth(aws_config.clone().try_into()?)
    .service_name("es") // use "aoss" for OpenSearch Serverless
    .build()?;
let client = OpenSearch::new(transport);

Re-exports§

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

Modules§

auth
Authentication components
cat
Cat APIs
cert
Certificate components
cluster
Cluster APIs
dangling_indices
Dangling Index APIs
http
HTTP components
indices
Index APIs
ingest
Ingest APIs
models
nodes
Node APIs
params
API parameters
snapshot
Snapshot APIs
tasks
Task Management APIs
text_structure
Text structure APIs

Structs§

Bulk
Builder for the Bulk API
BulkCreateOperation
Bulk create operation
BulkDeleteOperation
Bulk delete operation
BulkIndexOperation
Bulk index operation
BulkOperation
A bulk operation consists of a header that indicates the bulk action and the related metadata for the action, and an optional source document.
BulkOperations
A collection of bulk operations.
BulkUpdateOperation
Bulk update operation
ClearScroll
Builder for the Clear Scroll API
Count
Builder for the Count API
Create
Builder for the Create API
CreatePit
Builder for the Create Pit API
Delete
Builder for the Delete API
DeleteAllPits
Builder for the Delete All Pits API
DeleteByQuery
Builder for the Delete By Query API
DeleteByQueryRethrottle
Builder for the Delete By Query Rethrottle API
DeletePit
Builder for the Delete Pit API
DeleteScript
Builder for the Delete Script API
Error
An error with the client.
Exists
Builder for the Exists API
ExistsSource
Builder for the Exists Source API
Explain
Builder for the Explain API
FieldCaps
Builder for the Field Caps API
Get
Builder for the Get API
GetAllPits
Builder for the Get All Pits API
GetScript
Builder for the Get Script API
GetScriptContext
Builder for the Get Script Context API
GetScriptLanguages
Builder for the Get Script Languages API
GetSource
Builder for the Get Source API
Index
Builder for the Index API
Info
Builder for the Info API
Mget
Builder for the Mget API
Msearch
Builder for the Msearch API
MsearchTemplate
Builder for the Msearch Template API
Mtermvectors
Builder for the Mtermvectors API
OpenSearch
Root client for top level APIs
Ping
Builder for the Ping API
PutScript
Builder for the Put Script API
RankEval
Builder for the Rank Eval API
Reindex
Builder for the Reindex API
ReindexRethrottle
Builder for the Reindex Rethrottle API
RenderSearchTemplate
Builder for the Render Search Template API
ScriptsPainlessExecute
Builder for the Scripts Painless Execute API
Scroll
Builder for the Scroll API
Search
Builder for the Search API
SearchShards
Builder for the Search Shards API
SearchTemplate
Builder for the Search Template API
Termvectors
Builder for the Termvectors API
Update
Builder for the Update API
UpdateByQuery
Builder for the Update By Query API
UpdateByQueryRethrottle
Builder for the Update By Query Rethrottle API

Enums§

BulkParts
API parts for the Bulk API
ClearScrollParts
API parts for the Clear Scroll API
CountParts
API parts for the Count API
CreateParts
API parts for the Create API
CreatePitParts
API parts for the Create Pit API
DeleteAllPitsParts
API parts for the Delete All Pits API
DeleteByQueryParts
API parts for the Delete By Query API
DeleteByQueryRethrottleParts
API parts for the Delete By Query Rethrottle API
DeleteParts
API parts for the Delete API
DeletePitParts
API parts for the Delete Pit API
DeleteScriptParts
API parts for the Delete Script API
ExistsParts
API parts for the Exists API
ExistsSourceParts
API parts for the Exists Source API
ExplainParts
API parts for the Explain API
FieldCapsParts
API parts for the Field Caps API
GetAllPitsParts
API parts for the Get All Pits API
GetParts
API parts for the Get API
GetScriptContextParts
API parts for the Get Script Context API
GetScriptLanguagesParts
API parts for the Get Script Languages API
GetScriptParts
API parts for the Get Script API
GetSourceParts
API parts for the Get Source API
IndexParts
API parts for the Index API
InfoParts
API parts for the Info API
MgetParts
API parts for the Mget API
MsearchParts
API parts for the Msearch API
MsearchTemplateParts
API parts for the Msearch Template API
MtermvectorsParts
API parts for the Mtermvectors API
PingParts
API parts for the Ping API
PutScriptParts
API parts for the Put Script API
RankEvalParts
API parts for the Rank Eval API
ReindexParts
API parts for the Reindex API
ReindexRethrottleParts
API parts for the Reindex Rethrottle API
RenderSearchTemplateParts
API parts for the Render Search Template API
ScriptsPainlessExecuteParts
API parts for the Scripts Painless Execute API
ScrollParts
API parts for the Scroll API
SearchParts
API parts for the Search API
SearchShardsParts
API parts for the Search Shards API
SearchTemplateParts
API parts for the Search Template API
TermvectorsParts
API parts for the Termvectors API
UpdateByQueryParts
API parts for the Update By Query API
UpdateByQueryRethrottleParts
API parts for the Update By Query Rethrottle API
UpdateParts
API parts for the Update API