Skip to main content

Overview

We can represent an Elasticsearch request as a generic data type ElasticRequest[A], where A represents the result of the executed request. The library offers a DSL for creating these requests, by specifying their required parameters.

For example, we can create a request for deleting a document with a specified index as follows:

ElasticRequest.deleteById(IndexName("index"), DocumentId("documentId"))

As you can see above, index names and document IDs are represented with IndexName and DocumentId respectively, using Newtypes from ZIO Prelude, to increase type-safety with no runtime overhead.

Elastic requests for creating and deleting return CreationOutcome and DeletionOutcome respectively, notifying us of the outcome of the request.

import zio._
import zio.elasticsearch._
import zio.elasticsearch.ElasticRequest._

val createIndexWithoutMappingResult: RIO[Elasticsearch, CreationOutcome] =
Elasticsearch.execute(createIndex(IndexName("index")))

val createIndexWithMappingResult: RIO[Elasticsearch, CreationOutcome] =
Elasticsearch.execute(createIndex(IndexName("index"), "..."))

val deleteIndexResult: RIO[Elasticsearch, DeletionOutcome] =
Elasticsearch.execute(deleteIndex(IndexName("index")))

All the DSL methods for request creation can be brought into scope with the following import:

import zio.elasticsearch.ElasticRequest._

Executing the getById request returns the following effect, where GetResult represents a successful value:

import zio._
import zio.elasticsearch._
import zio.elasticsearch.ElasticRequest._
import zio.elasticsearch.result.{DecodingException, GetResult}

val getByIdResult: RIO[Elasticsearch, GetResult] =
Elasticsearch.execute(getById(IndexName("index"), DocumentId("documentId")))

To return a document of custom type A, you must create a schema for A. Here is an example of creating a schema for a custom type User:

import zio.schema.{DeriveSchema, Schema}

final case class User(id: String, name: String, email: String, age: Int)

object User {
implicit val schema: Schema[User] = DeriveSchema.gen[User]
}

As long as we have the implicit schema value in scope, we can transform GetResult to a desired type A:

val getUserByIdResult: RIO[Elasticsearch, IO[DecodingException, Option[User]]] =
Elasticsearch.execute(getById(IndexName("index"), DocumentId("documentId")))
.map(_.documentAs[User])