Skip to content

Commit 41e3a5f

Browse files
committed
Add indexing and searching documentation
This commit adds documentation for indexing single and multiple documents, and searching.
1 parent 695a56a commit 41e3a5f

File tree

2 files changed

+171
-5
lines changed

2 files changed

+171
-5
lines changed

elasticsearch/src/lib.rs

Lines changed: 150 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
//! # use elasticsearch::Error;
8282
//! # use elasticsearch::Elasticsearch;
8383
//! # use url::Url;
84-
//! # use elasticsearch::http::transport::{Transport};
84+
//! # use elasticsearch::http::transport::Transport;
8585
//! # use elasticsearch::auth::Credentials;
8686
//! # async fn run() -> Result<(), Error> {
8787
//! let cloud_id = "cluster_name:Y2xvdWQtZW5kcG9pbnQuZXhhbXBsZSQzZGFkZjgyM2YwNTM4ODQ5N2VhNjg0MjM2ZDkxOGExYQ==";
@@ -118,6 +118,106 @@
118118
//! or on a _namespace_ client that groups related APIs, such as [Cat](cat::Cat), which groups the
119119
//! Cat related APIs. All API functions are `async` and can be `await`ed.
120120
//!
121+
//! The following makes an API call to the cat indices API
122+
//!
123+
//! ```rust,no_run
124+
//! # use elasticsearch;
125+
//! # use elasticsearch::{Elasticsearch, Error, cat::CatIndicesParts};
126+
//! # use url::Url;
127+
//! # use elasticsearch::auth::Credentials;
128+
//! # use serde_json::{json, Value};
129+
//! # async fn run() -> Result<(), Error> {
130+
//! # let client = Elasticsearch::default();
131+
//! let response = client
132+
//! .cat()
133+
//! .indices(CatIndicesParts::Index(&["*"]))
134+
//! .send()
135+
//! .await?;
136+
//!
137+
//! let response_body = response.read_body::<Value>().await?;
138+
//! for record in response_body.as_array().unwrap() {
139+
//! // print the name of each index
140+
//! println!("{}", record["index"].as_str().unwrap());
141+
//! }
142+
//! # Ok(())
143+
//! # }
144+
//! ```
145+
//! For APIs that contain parts of the Url path to be provided by the consumer, the Url path
146+
//! variants are modelled as an `enum`, such as [CatIndicesParts] in the above example, which models
147+
//! the variants of the [CatIndices] API.
148+
//!
149+
//! ### Indexing
150+
//!
151+
//! Indexing a single document can be achieved with the index API
152+
//!
153+
//! ```rust,no_run
154+
//! # use elasticsearch;
155+
//! # use elasticsearch::{Elasticsearch, Error, SearchParts, IndexParts};
156+
//! # use url::Url;
157+
//! # use elasticsearch::auth::Credentials;
158+
//! # use serde_json::{json, Value};
159+
//! # async fn run() -> Result<(), Error> {
160+
//! # let client = Elasticsearch::default();
161+
//! let response = client
162+
//! .index(IndexParts::IndexId("tweets", "1"))
163+
//! .body(json!({
164+
//! "id": 1,
165+
//! "user": "kimchy",
166+
//! "post_date": "2009-11-15T00:00:00Z",
167+
//! "message": "Trying out Elasticsearch, so far so good?"
168+
//! }))
169+
//! .send()
170+
//! .await?;
171+
//!
172+
//! let successful = response.status_code().is_success();
173+
//! # Ok(())
174+
//! # }
175+
//! ```
176+
//!
177+
//! For indexing multiple documents, the bulk API is a better option, allowing multiple operations
178+
//! to be sent in one API call
179+
//!
180+
//! ```rust,no_run
181+
//! # use elasticsearch;
182+
//! # use elasticsearch::{Elasticsearch, Error, IndexParts, BulkParts, http::request::JsonBody};
183+
//! # use url::Url;
184+
//! # use elasticsearch::auth::Credentials;
185+
//! # use serde_json::{json, Value};
186+
//! # async fn run() -> Result<(), Error> {
187+
//! # let client = Elasticsearch::default();
188+
//! let mut body: Vec<JsonBody<_>> = Vec::with_capacity(4);
189+
//!
190+
//! // add the first operation and document
191+
//! body.push(json!({"index": {"_id": "1"}}).into());
192+
//! body.push(json!({
193+
//! "id": 1,
194+
//! "user": "kimchy",
195+
//! "post_date": "2009-11-15T00:00:00Z",
196+
//! "message": "Trying out Elasticsearch, so far so good?"
197+
//! }).into());
198+
//!
199+
//! // add the second operation and document
200+
//! body.push(json!({"index": {"_id": "2"}}).into());
201+
//! body.push(json!({
202+
//! "id": 2,
203+
//! "user": "forloop",
204+
//! "post_date": "2020-01-08T00:00:00Z",
205+
//! "message": "Bulk indexing with the rust client, yeah!"
206+
//! }).into());
207+
//!
208+
//! let response = client
209+
//! .bulk(BulkParts::Index("tweets"))
210+
//! .body(body)
211+
//! .send()
212+
//! .await?;
213+
//!
214+
//! let response_body = response.read_body::<Value>().await?;
215+
//! let successful = response_body["errors"].as_bool().unwrap() == false;
216+
//! # Ok(())
217+
//! # }
218+
//! ```
219+
//! ### Searching
220+
//!
121221
//! The following makes an API call to `tweets/_search` with the json body
122222
//! `{"query":{"match":{"message":"Elasticsearch"}}}`
123223
//!
@@ -136,7 +236,7 @@
136236
//! .body(json!({
137237
//! "query": {
138238
//! "match": {
139-
//! "message": "Elasticsearch"
239+
//! "message": "Elasticsearch rust"
140240
//! }
141241
//! }
142242
//! }))
@@ -145,12 +245,57 @@
145245
//!
146246
//! let response_body = response.read_body::<Value>().await?;
147247
//! let took = response_body["took"].as_i64().unwrap();
248+
//! for hit in response_body["hits"]["hits"].as_array().unwrap() {
249+
//! // print the source document
250+
//! println!("{:?}", hit["_source"]);
251+
//! }
148252
//! # Ok(())
149253
//! # }
150254
//! ```
151-
//! For APIs that contain parts of the Url path to be provided by the consumer, the Url path
152-
//! variants are modelled as an `enum`, such as [SearchParts] in the above example, which models
153-
//! the variants of the [Search] API.
255+
//!
256+
//! ## Request bodies
257+
//!
258+
//! For APIs that expect JSON, the `body` associated function of the API constrains the input
259+
//! to a type that implements [serde::Serialize] trait. An example of this was the indexing a single
260+
//! document example above.
261+
//!
262+
//! Some APIs expect newline delimited JSON
263+
//! (NDJSON) however, so the `body` associated for these APIs constrain the input to a vector of
264+
//! types that implement [Body] trait. An example of this was the bulk indexing multiple documents
265+
//! above.
266+
//!
267+
//! The [Body] trait represents the body of an API call, allowing for different body implementations.
268+
//! As well as those to represent JSON and NDJSON, a few other types also have implementations for
269+
//! [Body], such as byte slice. Whilst these can't be passed to the API functions directly,
270+
//! [Elasticsearch::send] can be used
271+
//!
272+
//! ```rust,no_run
273+
//! # use elasticsearch;
274+
//! # use elasticsearch::{Elasticsearch, Error, SearchParts};
275+
//! # use url::Url;
276+
//! # use elasticsearch::auth::Credentials;
277+
//! # use serde_json::{json, Value};
278+
//! # use http::HeaderMap;
279+
//! # use elasticsearch::http::Method;
280+
//! # async fn run() -> Result<(), Error> {
281+
//! # let client = Elasticsearch::default();
282+
//! let body = b"{\"query\":{\"match_all\":{}}}";
283+
//!
284+
//! let response = client
285+
//! .send(Method::Post,
286+
//! SearchParts::Index(&["tweets"]).url().as_ref(),
287+
//! HeaderMap::new(),
288+
//! Option::<&Value>::None,
289+
//! Some(body.as_ref())
290+
//! )
291+
//! .await?;
292+
//!
293+
//! # Ok(())
294+
//! # }
295+
//! ```
296+
//!
297+
//!
298+
//!
154299
//!
155300
156301
// also test examples in README

elasticsearch/tests/client.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use hyper::Method;
99
use reqwest::StatusCode;
1010
use serde_json::{json, Value};
1111
use http::header::HeaderName;
12+
use http::HeaderMap;
1213

1314
#[tokio::test]
1415
async fn default_user_agent_content_type_accept_headers() -> Result<(), failure::Error> {
@@ -158,3 +159,23 @@ async fn clone_search_with_body() -> Result<(), failure::Error> {
158159

159160
Ok(())
160161
}
162+
163+
#[tokio::test]
164+
async fn byte_slice_body() -> Result<(), failure::Error> {
165+
let client = client::create_default();
166+
let body = b"{\"query\":{\"match_all\":{}}}";
167+
168+
let response = client
169+
.send(elasticsearch::http::Method::Post,
170+
SearchParts::None.url().as_ref(),
171+
HeaderMap::new(),
172+
Option::<&Value>::None,
173+
Some(body.as_ref())
174+
)
175+
.await?;
176+
177+
assert_eq!(response.status_code(), StatusCode::OK);
178+
let _response_body = response.read_body::<Value>().await?;
179+
180+
Ok(())
181+
}

0 commit comments

Comments
 (0)