Dowser.Envelope (Dowser.Client v0.5.0)

View Source

Finds the documents in a response body, at any depth, and casts each one with Dowser.Source against its own index's mapping.

A document is a map with a string "_index" and a map "_source": a bare document (a GET /{index}/_doc/{id}), each of hits.hits[] (a search), responses[].hits.hits[] (a multi-search), docs[] (a multi-get), and so on. Each one's "_index" selects its mapping, so a mixed-index result is cast correctly.

A hit's inner_hits are cast too. They carry no _index of their own, so their mapping comes from the hit they belong to: _nested.field names the path into it, and an inner hit with no _nested (a has_child or has_parent join) is cast against the index mapping itself. The rest of a hit's envelope — fields, highlight, sort — has no mapping entry to be cast against, and only has its keys run through :key_fn.

Everything around the documents is envelope too: its keys go through :key_fn, its values are left alone.

With a :struct (a Dowser.Schema module), each hit's _source is loaded into that struct by its __load__/2, which also receives the hit's metadata as :meta; inner hits — parts of a document, not documents — stay maps.

:key_fn casts the keys of maps — the envelope, map sources, inner hits — and never the fields of a struct.

Summary

Functions

Casts every document found in body.

Functions

load(body, mapping_fn, opts \\ [])

@spec load(term(), (term() -> map() | nil), keyword()) :: term()

Casts every document found in body.

mapping_fn returns the mapping for an index name (nil when there is none). opts are Dowser.Source's — :key_fn (default: identity), :types, :opaque, :unknown_fields — plus :struct.

iex> mapping = %{"properties" => %{"ip" => %{"type" => "ip"}}}
iex> body = %{"hits" => %{"hits" => [%{"_index" => "hosts", "_source" => %{"ip" => "127.0.0.1"}}]}}
iex> Dowser.Envelope.load(body, fn "hosts" -> mapping end)
%{"hits" => %{"hits" => [%{"_index" => "hosts", "_source" => %{"ip" => {127, 0, 0, 1}}}]}}