From 8af43f71dd6d029d672a990b41c48c88ccac8bcd Mon Sep 17 00:00:00 2001 From: "Kian-Meng, Ang" Date: Wed, 28 Jul 2021 21:45:58 +0800 Subject: [PATCH] Misc doc changes Besides other documentation changes, this commit ensures the generated HTML doc for HexDocs.pm will become the source of truth for this Elixir library and leverage on latest features of ExDoc. --- .formatter.exs | 2 +- .gitignore | 7 ++- LICENSE => LICENSE.md | 2 +- README.md | 31 +++++++--- lib/exlasticsearch.ex | 12 ++-- lib/exlasticsearch/aggregation.ex | 16 +++--- lib/exlasticsearch/bulk.ex | 4 +- lib/exlasticsearch/indexable.ex | 16 +++--- lib/exlasticsearch/model.ex | 26 ++++++--- lib/exlasticsearch/monitoring/mock.ex | 6 +- lib/exlasticsearch/query.ex | 42 +++++++------- lib/exlasticsearch/repo.ex | 57 +++++++++++-------- lib/exlasticsearch/response.ex | 16 +++--- lib/exlasticsearch/response/hits.ex | 2 +- lib/exlasticsearch/response/record.ex | 5 +- lib/exlasticsearch/response/search.ex | 2 +- lib/exlasticsearch/retry/decorator.ex | 9 ++- .../retry/exponential_backoff.ex | 4 +- lib/exlasticsearch/retry_strategy.ex | 4 +- lib/exlasticsearch/type_inference.ex | 15 +++-- lib/exlasticsearch/type_inference/base.ex | 6 +- mix.exs | 25 ++++---- mix.lock | 8 +-- 23 files changed, 182 insertions(+), 135 deletions(-) rename LICENSE => LICENSE.md (98%) diff --git a/.formatter.exs b/.formatter.exs index 525446d..d2cda26 100644 --- a/.formatter.exs +++ b/.formatter.exs @@ -1,4 +1,4 @@ # Used by "mix format" [ - inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"] + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] ] diff --git a/.gitignore b/.gitignore index 40493b3..67e8f88 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,7 @@ # The directory Mix downloads your dependencies sources to. /deps/ -# Where 3rd-party dependencies like ExDoc output generated docs. +# Where third-party dependencies like ExDoc output generated docs. /doc/ # Ignore .fetch files in case you like to edit your project deps locally. @@ -22,6 +22,9 @@ erl_crash.dump # Ignore package tarball (built via "mix hex.build"). exlasticsearch-*.tar -.elixir_ls/ +# Temporary files for e.g. tests +/tmp/ + +# Misc. /tags /TAGS diff --git a/LICENSE b/LICENSE.md similarity index 98% rename from LICENSE rename to LICENSE.md index bad78c3..3c602f4 100644 --- a/LICENSE +++ b/LICENSE.md @@ -1,4 +1,4 @@ -MIT License +# MIT License Copyright (c) 2018 Frame.io diff --git a/README.md b/README.md index e2cedcd..9c27a47 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,14 @@ # ExlasticSearch -An elasticsearch dsls for mapping ecto models to elasticsearch mappings, along with elixir -friendly query wrappers, response formatting and the like. +[![Module Version](https://img.shields.io/hexpm/v/exlasticsearch.svg)](https://hex.pm/packages/exlasticsearch) +[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/exlasticsearch/) +[![Total Download](https://img.shields.io/hexpm/dt/exlasticsearch.svg)](https://hex.pm/packages/exlasticsearch) +[![License](https://img.shields.io/hexpm/l/exlasticsearch.svg)](https://github.com/Frameio/exlasticsearch/blob/master/LICENSE) +[![Last Updated](https://img.shields.io/github/last-commit/Frameio/exlasticsearch.svg)](https://github.com/Frameio/exlasticsearch/commits/master) + +An [Elasticsearch](https://www.elastic.co/elasticsearch/) DSLs for mapping Ecto +models to Elasticsearch mappings, along with Elixir friendly query wrappers, +response formatting and the like. ## Installation @@ -13,11 +20,11 @@ def deps do end ``` -Docs are available on [hex](https://hexdocs.pm/exlasticsearch/0.2.2) +Docs are available on [hex](https://hexdocs.pm/exlasticsearch/) ## Usage -You can pair an ExlasticSearch.Model with an existing schema like: +You can pair an `ExlasticSearch.Model` with an existing schema like: ```elixir defmodule MySchema do @@ -37,13 +44,13 @@ You can then construct queries like so: ```elixir MySchema.search_query() -|> must(math(field, value)) -|> should(match_phrash(field, value, opts)) +|> must(match(field, value)) +|> should(match_phrase(field, value, opts)) |> filter(term(filter_field, value)) ``` -A repo model like ecto is provided, so a with ability to do most restful operations on records, in -addition to calling search apis with the query structs above. +A Repo model like Ecto is provided, so a with ability to do most restful operations on records, in +addition to calling search APIs with the query structs above. If additional data needs to be fetched or formatted prior to insertion into elastic, the `ExlasticSearch.Indexable` protocol can be implemented to do that for you. A default implementation can also be generated as part of using @@ -51,7 +58,7 @@ the `ExlasticSearch.Model` macro. ## Configuration -This library requires `elastix` (an elixir elasticsearch http client). So refer to it for any http related configuration. In addition, there are the following config options: +This library requires `elastix` (an Elixir Elasticsearch HTTP client). So refer to it for any HTTP related configuration. In addition, there are the following config options: ```elixir config :exlasticsearch, :type_inference, ExlasticSearch.TypeInference @@ -61,3 +68,9 @@ config :exlasticsearch, :monitoring, ExlasticSearch.Monitoring.Mock config :exlasticsearch, ExlasticSearch.Repo, url: "http://localhost:9200" ``` + +## Copyright and License + +Copyright (c) 2018 Frame.io + +This software is released under the [MIT License](./LICENSE.md). diff --git a/lib/exlasticsearch.ex b/lib/exlasticsearch.ex index 1842ff2..d9c6680 100644 --- a/lib/exlasticsearch.ex +++ b/lib/exlasticsearch.ex @@ -1,9 +1,9 @@ defmodule ExlasticSearch do @moduledoc """ - A collection of elasticsearch dsl's to make development simple. The usage is meant to - pair with existing ecto schema, like so: + A collection of Elasticsearch DSLs to make development simple. The usage is meant to + pair with existing Ecto schema, like so: - ``` + ```elixir defmodule MySchema do ... use ExlasticSearch.Model @@ -19,14 +19,14 @@ defmodule ExlasticSearch do You can then construct queries like so: - ``` + ```elixir MySchema.search_query() - |> must(math(field, value)) + |> must(match(field, value)) |> should(match_phrase(field, value, opts)) |> filter(term(filter_field, value)) ``` - A repo model like ecto is provided, so a with ability to do most restful operations on records, in + A Repo model like Ecto is provided, so a with ability to do most restful operations on records, in addition to calling search apis with the query structs above. If additional data needs to be fetched or formatted prior to insertion into elastic, the `ExlasticSearch.Indexable` diff --git a/lib/exlasticsearch/aggregation.ex b/lib/exlasticsearch/aggregation.ex index 33e8f1a..b0ef8f3 100644 --- a/lib/exlasticsearch/aggregation.ex +++ b/lib/exlasticsearch/aggregation.ex @@ -1,24 +1,24 @@ defmodule ExlasticSearch.Aggregation do @moduledoc """ - Elasticsearch aggregation building functions + Elasticsearch aggregation building functions. """ defstruct [aggregations: [], nested: %{}, options: %{}] @type t :: %__MODULE__{} - @doc "create a new aggregation specification" + @doc "create a new aggregation specification." def new(), do: %__MODULE__{} @doc """ - Bucket a query by a given term + Bucket a query by a given term. """ def terms(%{aggregations: aggs} = agg, name, options) do %{agg | aggregations: [{name, %{terms: Enum.into(options, %{})}} | aggs]} end @doc """ - A composite aggregation + A composite aggregation. """ def composite(%{aggregations: aggs} = agg, name, sources, opts \\ []) do options = Enum.into(opts, %{}) @@ -26,26 +26,26 @@ defmodule ExlasticSearch.Aggregation do end @doc """ - The source for a composite aggregation, eg `composite_source(:age, :terms, field: :age)` + The source for a composite aggregation, eg `composite_source(:age, :terms, field: :age)`. """ def composite_source(name, type, opts), do: %{name => %{type => Enum.into(opts, %{})}} @doc """ - Return the top results for a query or aggregation scope + Return the top results for a query or aggregation scope. """ def top_hits(%{aggregations: aggs} = agg, name, options) do %{agg | aggregations: [{name, %{top_hits: Enum.into(options, %{})}} | aggs]} end @doc """ - Includes a given aggregation within the aggregation with name `name` + Includes a given aggregation within the aggregation with name `name`. """ def nest(%{nested: nested} = agg, name, nest) do %{agg | nested: Map.put(nested, name, nest)} end @doc """ - Convert to the es representation of the aggregation + Convert to the es representation of the aggregation. """ def realize(%__MODULE__{aggregations: aggs, nested: nested, options: opts}) do %{aggs: Enum.into(aggs, %{}, fn {key, agg} -> {key, with_nested(realize(agg), nested, key)} end) diff --git a/lib/exlasticsearch/bulk.ex b/lib/exlasticsearch/bulk.ex index b4ea9e4..387f514 100644 --- a/lib/exlasticsearch/bulk.ex +++ b/lib/exlasticsearch/bulk.ex @@ -1,13 +1,13 @@ defmodule ExlasticSearch.BulkOperation do @moduledoc """ - Handles bulk request generation + Handles bulk request generation. """ alias ExlasticSearch.Indexable @doc """ Generates a request for inserts, updates and deletes - that can be sent as a bulk request using Elastix + that can be sent as a bulk request using Elastix. """ def bulk_operation({:delete, _struct, _index} = instruction), do: bulk_operation_delete(instruction) diff --git a/lib/exlasticsearch/indexable.ex b/lib/exlasticsearch/indexable.ex index e8abee7..ea76589 100644 --- a/lib/exlasticsearch/indexable.ex +++ b/lib/exlasticsearch/indexable.ex @@ -1,26 +1,28 @@ defprotocol ExlasticSearch.Indexable do @moduledoc """ - Protocol for converting Ecto structs to ES-compatible maps. `ExlasticSearch.Repo` uses - this internally to effect any conversion prior to communicating with elasticsearch itself + Protocol for converting Ecto structs to ES-compatible maps. + + `ExlasticSearch.Repo` uses this internally to effect any conversion prior to + communicating with elasticsearch itself """ - @doc "ES record id" + @doc "ES record id." @spec id(struct) :: binary def id(_) - @doc "Properties map to be inserted into ES" + @doc "Properties map to be inserted into ES." @spec document(struct, atom) :: map def document(_, _) - @doc "Properties map to be inserted into ES" + @doc "Properties map to be inserted into ES." @spec document(struct) :: map def document(_) - @doc "Any preloads needed to call `document/2`" + @doc "Any preloads needed to call `document/2`." @spec preload(struct, atom) :: struct def preload(_, _) - @doc "Any preloads needed to call `document/2`" + @doc "Any preloads needed to call `document/2`." @spec preload(struct) :: struct def preload(_) end diff --git a/lib/exlasticsearch/model.ex b/lib/exlasticsearch/model.ex index 9c9e11d..5a8f94b 100644 --- a/lib/exlasticsearch/model.ex +++ b/lib/exlasticsearch/model.ex @@ -1,7 +1,9 @@ defmodule ExlasticSearch.Model do @moduledoc """ - Base macro for generating elasticsearch modules. Is intended to be used in conjunction with a - Ecto model (although that is not strictly necessary). + Base macro for generating elasticsearch modules. + + Is intended to be used in conjunction with a Ecto model (although that is not + strictly necessary). It includes three primary macros: @@ -11,7 +13,7 @@ defmodule ExlasticSearch.Model do The usage is something like this - ``` + ```elixir indexes :my_type do settings Application.get_env(:some, :settings) @@ -60,8 +62,10 @@ defmodule ExlasticSearch.Model do end @doc """ - Opens up index definition for the current model. Will name the index and generate metadata - attributes for the index based on subsequent calls to `settings/1` and `mappings/2`. + Opens up index definition for the current model. + + Will name the index and generate metadata attributes for the index based on + subsequent calls to `settings/1` and `mappings/2`. Accepts * `type` - the indexes type (and index name will be `type <> "s"`) @@ -122,7 +126,7 @@ defmodule ExlasticSearch.Model do defmodule SearchResult do @moduledoc """ - Wrapper for a models search result. Used for response parsing + Wrapper for a models search result. Used for response parsing. """ defmacro __using__(_) do columns = __CALLER__.module.__mappings__() @@ -136,7 +140,9 @@ defmodule ExlasticSearch.Model do end @doc """ - Adds a new mapping to the ES schema. The type of the mapping will be inferred automatically, unless explictly set + Adds a new mapping to the ES schema. + + The type of the mapping will be inferred automatically, unless explictly set in props. Accepts: @@ -150,7 +156,9 @@ defmodule ExlasticSearch.Model do end @doc """ - A map of index settings. Structure is the same as specified by ES. + A map of index settings. + + Structure is the same as specified by ES. """ defmacro settings(settings) do quote do @@ -183,7 +191,7 @@ defmodule ExlasticSearch.Model do end @doc """ - Converts a search result to `model`'s search result type + Converts a search result to `model`'s search result type. """ def es_decode(source, model) do model.__es_decode_template__() diff --git a/lib/exlasticsearch/monitoring/mock.ex b/lib/exlasticsearch/monitoring/mock.ex index 0c282d8..96862cb 100644 --- a/lib/exlasticsearch/monitoring/mock.ex +++ b/lib/exlasticsearch/monitoring/mock.ex @@ -1,6 +1,8 @@ defmodule ExlasticSearch.Monitoring.Mock do @moduledoc """ - Noop implementation of monitoring. To bring your own, do `config :exlasticsearch, :monitoring, MonitoringModule` + Noop implementation of monitoring. + + To bring your own, do `config :exlasticsearch, :monitoring, MonitoringModule` """ def increment(_, _), do: nil -end \ No newline at end of file +end diff --git a/lib/exlasticsearch/query.ex b/lib/exlasticsearch/query.ex index 3daabaf..0bb1173 100644 --- a/lib/exlasticsearch/query.ex +++ b/lib/exlasticsearch/query.ex @@ -1,11 +1,13 @@ defmodule ExlasticSearch.Query do @moduledoc """ - Elasticsearch query building functions. Basic usage for queryable Queryable is something like: + Elasticsearch query building functions. - ``` + Basic usage for queryable Queryable is something like: + + ```elixir Queryable.search_query() - |> must(math(field, value)) - |> should(match_phrash(field, value, opts)) + |> must(match(field, value)) + |> should(match_phrase(field, value, opts)) |> filter(term(filter_field, value)) |> realize() ``` @@ -37,14 +39,14 @@ defmodule ExlasticSearch.Query do @query_keys [:must, :should, :filter, :must_not] @doc """ - Builds a match phrase query clause + Builds a match phrase query clause. """ @spec match_phrase(atom, binary, Keyword.t) :: map def match_phrase(field, query, opts \\ []), do: %{match_phrase: %{field => Enum.into(opts, %{query: query})}} @doc """ - Builds a match query clause + Builds a match query clause. """ @spec match(atom, binary) :: map def match(field, query), do: %{match: %{field => query}} @@ -53,76 +55,76 @@ defmodule ExlasticSearch.Query do def match(field, query, opts), do: %{match: %{field => Enum.into(opts, %{query: query})}} @doc """ - Multimatch query clause + Multimatch query clause. """ @spec multi_match(atom, binary) :: map def multi_match(fields, query, opts \\ []), do: %{multi_match: Enum.into(opts, %{query: query, fields: fields, type: :best_fields})} @doc """ - Term query clause + Term query clause. """ @spec term(atom, binary) :: map def term(field, term), do: %{term: %{field => term}} @doc """ - ids query clause + ids query clause. """ @spec ids(list) :: map def ids(ids), do: %{ids: %{values: ids}} @doc """ - Query string query type, that applies ES standard query rewriting + Query string query type, that applies ES standard query rewriting. """ @spec query_string(atom, Keyword.t) :: map def query_string(query, opts \\ []), do: %{query_string: Enum.into(opts, %{query: query})} @doc """ - terms query clause + terms query clause. """ @spec terms(atom, list) :: map def terms(field, terms), do: %{terms: %{field => terms}} @doc """ - range query clause + range query clause. """ @spec range(atom, map) :: map def range(field, range), do: %{range: %{field => range}} @doc """ - Appends a new filter scope to the running query + Appends a new filter scope to the running query. """ @spec filter(t, map) :: t def filter(%__MODULE__{filter: filters} = query, filter), do: %{query | filter: [filter | filters]} @doc """ - Appends a new must scope to the runnning query + Appends a new must scope to the runnning query. """ @spec must(t, map) :: t def must(%__MODULE__{must: musts} = query, must), do: %{query | must: [must | musts]} @doc """ - Appends a new should scope to the running query + Appends a new should scope to the running query. """ @spec should(t, map) :: t def should(%__MODULE__{should: shoulds} = query, should), do: %{query | should: [should | shoulds]} @doc """ - Appends a new must_not scope to the running query + Appends a new must_not scope to the running query. """ @spec must_not(t, map) :: t def must_not(%__MODULE__{must_not: must_nots} = query, must_not), do: %{query | must_not: [must_not | must_nots]} @doc """ - Adds a sort clause to the ES query + Adds a sort clause to the ES query. """ @spec sort(t, binary | atom, binary) :: t def sort(%__MODULE__{sort: sorts} = query, field, direction \\ "asc"), do: %{query | sort: [{field, direction} | sorts]} @doc """ - Converts a query to a function score query and adds the given `script` for scoring + Converts a query to a function score query and adds the given `script` for scoring. """ @spec script_score(t, binary, Keyword.t) :: t def script_score(%__MODULE__{options: options} = q, script, opts \\ []) do @@ -145,7 +147,7 @@ defmodule ExlasticSearch.Query do end @doc """ - Converts a `Query` struct into an ES compliant bool or function score compound query + Converts a `Query` struct into an ES compliant bool or function score compound query. """ @spec realize(t) :: map def realize(%__MODULE__{type: :nested} = query) do @@ -162,7 +164,7 @@ defmodule ExlasticSearch.Query do do: %{query: query_clause(query)} |> add_sort(query) @doc """ - Add options to the current bool compound query (for instance the minimum number of accepted matches) + Add options to the current bool compound query (for instance the minimum number of accepted matches). """ @spec options(t, map) :: t def options(%__MODULE__{} = query, opts), do: %{query | options: Map.new(opts)} diff --git a/lib/exlasticsearch/repo.ex b/lib/exlasticsearch/repo.ex index f8b668a..63d66f2 100644 --- a/lib/exlasticsearch/repo.ex +++ b/lib/exlasticsearch/repo.ex @@ -1,13 +1,17 @@ defmodule ExlasticSearch.Repo do @moduledoc """ - API executor for elasticsearch. The generate pattern is to define a `ExlasticSearch.Model` - on an ecto model, then call any of these functions to manage the model. + API executor for elasticsearch. + + The generate pattern is to define a `ExlasticSearch.Model` on an ecto model, + then call any of these functions to manage the model. To configure the url the repo points to, do: - ``` + ```elixir config :exlasticsearch, ExlasticSearch.Repo, url: "https://elasticsearch.url.io:9200" + ``` + """ use Scrivener use ExlasticSearch.Retry.Decorator @@ -22,7 +26,7 @@ defmodule ExlasticSearch.Repo do |> Keyword.get(:log_level, :debug) @doc """ - Creates an index as defined in `model` + Creates an index as defined in `model`. """ @spec create_index(atom) :: response def create_index(model, index \\ :index) do @@ -31,7 +35,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Updates the index for `model` + Updates the index for `model`. """ def update_index(model, index \\ :index) do url = es_url(index) <> "/#{model.__es_index__(index)}/_settings" @@ -39,7 +43,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Close an index for `model` + Close an index for `model`. """ def close_index(model, index \\ :index) do url = es_url(index) <> "/#{model.__es_index__(index)}/_close" @@ -47,7 +51,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - open an index for `model` + open an index for `model`. """ def open_index(model, index \\ :index) do url = es_url(index) <> "/#{model.__es_index__(index)}/_open" @@ -55,7 +59,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Updates an index's mappings to the current definition in `model` + Updates an index's mappings to the current definition in `model`. """ @spec create_mapping(atom) :: response def create_mapping(model, index \\ :index, opts \\ []) do @@ -64,7 +68,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Removes the index defined in `model` + Removes the index defined in `model`. """ @spec delete_index(atom) :: response def delete_index(model, index \\ :index) do @@ -75,12 +79,12 @@ defmodule ExlasticSearch.Repo do @doc """ Aliases one index version to another, for instance: - ``` + ```elixir alias(MyModel, read: :index) ``` will create an alias of the read version of the model's index - against it's indexing version + against it's indexing version. """ @spec create_alias(atom, [{atom, atom}]) :: response def create_alias(model, [{from, target}], index \\ :index) do @@ -104,7 +108,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Deletes the read index and aliases the write index to it + Deletes the read index and aliases the write index to it. """ @spec rotate(atom, atom, atom) :: response def rotate(model, read \\ :read, index \\ :index) do @@ -114,7 +118,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Retries the aliases for a given index + Retries the aliases for a given index. """ @spec get_alias(atom, atom) :: response def get_alias(model, index) when is_atom(index) do @@ -125,7 +129,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Checks if the index for `model` exists + Checks if the index for `model` exists. """ @spec exists?(atom) :: boolean def exists?(model, index \\ :read) do @@ -138,7 +142,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Refreshes `model`'s index + Refreshes `model`'s index. """ def refresh(model, index \\ :read) do es_url(index) @@ -146,8 +150,10 @@ defmodule ExlasticSearch.Repo do end @doc """ - Adds a struct into it's associated index. The struct will be passed through the `ExlasticSearch.Indexable` - protocol prior to insertion + Adds a struct into it's associated index. + + The struct will be passed through the `ExlasticSearch.Indexable` protocol + prior to insertion. """ @spec index(struct) :: response @decorate retry() @@ -162,7 +168,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Updates the document of the passed in id for the index associated to the model + Updates the document of the passed in id for the index associated to the model. """ @decorate retry() def update(model, id, data, index \\ :index) do @@ -175,8 +181,9 @@ defmodule ExlasticSearch.Repo do @doc """ Generates an Elasticsearch bulk request. `operations` should be of the form: - Note: the last element in each Tuple is optional and will default to :index - ``` + Note: the last element in each Tuple is optional and will default to `:index`. + + ```elixir [ {:index, struct, index}, {:delete, other_struct, index}, @@ -185,7 +192,7 @@ defmodule ExlasticSearch.Repo do ``` The function will handle formatting the bulk request properly and passing each - struct to the `ExlasticSearch.Indexable` protocol + struct to the `ExlasticSearch.Indexable` protocol. """ def bulk(operations, index \\ :index, query_params \\ [], opts \\ []) do bulk_request = @@ -210,7 +217,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Gets an ES document by _id + Gets an ES document by _id. """ @spec get(struct) ::{:ok, %Response.Record{}} | {:error, any} def get(%{__struct__: model} = struct, index_type \\ :read) do @@ -221,14 +228,14 @@ defmodule ExlasticSearch.Repo do end @doc """ - Creates a call to `search/3` by realizing `query` (using `Exlasticsearch.Query.realize/1`) and any provided search opts + Creates a call to `search/3` by realizing `query` (using `Exlasticsearch.Query.realize/1`) and any provided search opts. """ @spec search(Query.t(), list) :: {:ok, %Response.Search{}} | {:error, any} def search(%Query{queryable: model} = query, params), do: search(model, Query.realize(query), params, query.index_type || :read) @doc """ - Searches the index and type associated with `model` according to query `search` + Searches the index and type associated with `model` according to query `search`. """ @spec search(atom, map, list, any) :: {:ok, %Response.Search{}} | {:error, any} def search(model, search, params, index_type \\ :read) do @@ -271,7 +278,7 @@ defmodule ExlasticSearch.Repo do end @doc """ - Removes `struct` from the index of its model + Removes `struct` from the index of its model. """ @spec delete(struct) :: response @decorate retry() diff --git a/lib/exlasticsearch/response.ex b/lib/exlasticsearch/response.ex index c6304a5..0954113 100644 --- a/lib/exlasticsearch/response.ex +++ b/lib/exlasticsearch/response.ex @@ -1,10 +1,12 @@ defmodule ExlasticSearch.Response do @moduledoc """ - Base module for ES response parsing. Works off a few macros, `schema/1`, `field/1`, `has_many/2`, `has_one/2` + Base module for ES response parsing. + + Works off a few macros, `schema/1`, `field/1`, `has_many/2`, `has_one/2` The usage is more or less: - ``` + ```elixir use ExlasticSearch.Response schema do @@ -40,7 +42,7 @@ defmodule ExlasticSearch.Response do end @doc """ - Utility for recursively parsing response associations + Utility for recursively parsing response associations. """ def parse_associations(response, associations, model, index_type) do associations @@ -51,7 +53,7 @@ defmodule ExlasticSearch.Response do end @doc """ - Safe conversion of string keyed ES response maps to structifiable atom keyed maps + Safe conversion of string keyed ES response maps to structifiable atom keyed maps. """ def convert_keys(conversion_table, map) when is_map(map) do conversion_table @@ -98,7 +100,7 @@ defmodule ExlasticSearch.Response do end @doc """ - Adds a simple field attribute + Adds a simple field attribute. """ defmacro field(field) do quote do @@ -107,7 +109,7 @@ defmodule ExlasticSearch.Response do end @doc """ - Adds a has_many relation or the parser, which assumes a list value + Adds a has_many relation or the parser, which assumes a list value. Accepts: * field - the name of the relation @@ -120,7 +122,7 @@ defmodule ExlasticSearch.Response do end @doc """ - Adds a has_one relation or the parser + Adds a has_one relation or the parser. Accepts: * field - the name of the relation diff --git a/lib/exlasticsearch/response/hits.ex b/lib/exlasticsearch/response/hits.ex index c707a2d..8a0b8e4 100644 --- a/lib/exlasticsearch/response/hits.ex +++ b/lib/exlasticsearch/response/hits.ex @@ -1,6 +1,6 @@ defmodule ExlasticSearch.Response.Hits do @moduledoc """ - Elasticsearch hits response structure + Elasticsearch hits response structure. """ use ExlasticSearch.Response diff --git a/lib/exlasticsearch/response/record.ex b/lib/exlasticsearch/response/record.ex index 635244d..75cf980 100644 --- a/lib/exlasticsearch/response/record.ex +++ b/lib/exlasticsearch/response/record.ex @@ -1,7 +1,8 @@ defmodule ExlasticSearch.Response.Record do @moduledoc """ - Elasticsearch record response structure. `:_source` can contain a parsed - model result if properly specified + Elasticsearch record response structure. + + `:_source` can contain a parsed model result if properly specified. """ use ExlasticSearch.Response diff --git a/lib/exlasticsearch/response/search.ex b/lib/exlasticsearch/response/search.ex index f016339..e870e20 100644 --- a/lib/exlasticsearch/response/search.ex +++ b/lib/exlasticsearch/response/search.ex @@ -1,6 +1,6 @@ defmodule ExlasticSearch.Response.Search do @moduledoc """ - Elasticsearch Search response structure + Elasticsearch Search response structure. """ use ExlasticSearch.Response alias ExlasticSearch.Response.Hits diff --git a/lib/exlasticsearch/retry/decorator.ex b/lib/exlasticsearch/retry/decorator.ex index c48cd2c..8342dbe 100644 --- a/lib/exlasticsearch/retry/decorator.ex +++ b/lib/exlasticsearch/retry/decorator.ex @@ -1,10 +1,13 @@ defmodule ExlasticSearch.Retry.Decorator do @moduledoc """ - Decorator for applying retry strategies to a function. Configure with + Decorator for applying retry strategies to a function. - ``` + Configure with: + + ```elixir config :exlasticsearch, :retry, strategy: MyStrategy, additional_opts ``` + """ use Decorator.Define, retry: 0 @config Application.get_env(:exlasticsearch, :retry, []) @@ -15,4 +18,4 @@ defmodule ExlasticSearch.Retry.Decorator do unquote(strategy).retry(fn -> unquote(body) end, unquote(config)) end end -end \ No newline at end of file +end diff --git a/lib/exlasticsearch/retry/exponential_backoff.ex b/lib/exlasticsearch/retry/exponential_backoff.ex index 1774f06..510a1fe 100644 --- a/lib/exlasticsearch/retry/exponential_backoff.ex +++ b/lib/exlasticsearch/retry/exponential_backoff.ex @@ -1,6 +1,6 @@ defmodule ExlasticSearch.Retry.ExponentialBackoff do @moduledoc """ - Retry Strategy implementation utilizing exponential backoffs + Retry Strategy implementation utilizing exponential backoffs. """ @behaviour ExlasticSearch.RetryStrategy @@ -29,4 +29,4 @@ defmodule ExlasticSearch.Retry.ExponentialBackoff do exp = :math.pow(2, retry) |> round() jitter + (initial * exp) end -end \ No newline at end of file +end diff --git a/lib/exlasticsearch/retry_strategy.ex b/lib/exlasticsearch/retry_strategy.ex index b4fe580..8e1d927 100644 --- a/lib/exlasticsearch/retry_strategy.ex +++ b/lib/exlasticsearch/retry_strategy.ex @@ -1,8 +1,8 @@ defmodule ExlasticSearch.RetryStrategy do @moduledoc """ - Behavior for retrying a 0-arity function according to some strategy + Behavior for retrying a 0-arity function according to some strategy. """ @type response :: {:ok, any} | {:error, any} @type callable :: (-> {:ok, any} | {:error, any}) @callback retry(fnc :: callable, opts :: list) :: response -end \ No newline at end of file +end diff --git a/lib/exlasticsearch/type_inference.ex b/lib/exlasticsearch/type_inference.ex index de2b070..d7c5aae 100644 --- a/lib/exlasticsearch/type_inference.ex +++ b/lib/exlasticsearch/type_inference.ex @@ -1,8 +1,10 @@ defmodule ExlasticSearch.TypeInference do @moduledoc """ - Default type inference implementation. If you desire to override it, simply do: + Default type inference implementation. - ``` + If you desire to override it, simply do: + + ```elixir defmodule MyTypeInference do use ExlasticSearch.TypeInference.Base @@ -11,15 +13,16 @@ defmodule ExlasticSearch.TypeInference do end ``` - Then configure it with `config :exlasticsearch, :type_inference, MyTypeInference` + Then configure it with `config :exlasticsearch, :type_inference, MyTypeInference`. """ defmodule API do @moduledoc """ - Behaviour for inferring module types. A default implementation is available - in ExlasticSearch.TypeInference.Base + Behaviour for inferring module types. + + A default implementation is available in `ExlasticSearch.TypeInference.Base`. """ @callback infer(atom) :: atom end use ExlasticSearch.TypeInference.Base -end \ No newline at end of file +end diff --git a/lib/exlasticsearch/type_inference/base.ex b/lib/exlasticsearch/type_inference/base.ex index c3122ec..11d0f48 100644 --- a/lib/exlasticsearch/type_inference/base.ex +++ b/lib/exlasticsearch/type_inference/base.ex @@ -1,11 +1,11 @@ defmodule ExlasticSearch.TypeInference.Base do @moduledoc """ - Implementation of type infernce for builtin ecto types + Implementation of type inference for builtin Ecto types. """ defmacro __using__(_) do quote do @behaviour ExlasticSearch.TypeInference.API - + def infer(:binary_id), do: :keyword def infer(:integer), do: :long def infer(:float), do: :double @@ -17,4 +17,4 @@ defmodule ExlasticSearch.TypeInference.Base do defoverridable [infer: 1] end end -end \ No newline at end of file +end diff --git a/mix.exs b/mix.exs index 53e9b7d..d234259 100644 --- a/mix.exs +++ b/mix.exs @@ -1,6 +1,7 @@ defmodule Exlasticsearch.MixProject do use Mix.Project + @source_url "https://github.com/Frameio/exlasticsearch" @version "2.2.1" def project do @@ -9,15 +10,13 @@ defmodule Exlasticsearch.MixProject do version: @version, elixir: "~> 1.6", start_permanent: Mix.env() == :prod, - elixirc_paths: elixirc_paths(Mix.env), - description: description(), + elixirc_paths: elixirc_paths(Mix.env()), package: package(), deps: deps(), docs: docs() ] end - # Run "mix help compile.app" to learn about applications. def application do [ extra_applications: [:logger] @@ -27,7 +26,6 @@ defmodule Exlasticsearch.MixProject do defp elixirc_paths(:test), do: ["lib", "test/support"] defp elixirc_paths(_), do: ["lib"] - # Run "mix help deps" to learn about dependencies. defp deps do [ {:flow, "~> 1.0"}, @@ -36,28 +34,31 @@ defmodule Exlasticsearch.MixProject do {:ecto, ">= 2.1.0"}, {:scrivener_ecto, "~> 2.0"}, {:decorator, "~> 1.2"}, - {:ex_doc, "~> 0.19.1", only: :dev} + {:ex_doc, ">= 0.0.0", only: :dev, runtime: false} ] end defp docs() do [ + extras: [ + "LICENSE.md": [title: "License"], + "README.md": [title: "Overview"] + ], main: "readme", - extras: ["README.md"], + source_url: @source_url, source_ref: "v#{@version}", - source_url: "https://github.com/Frameio/exlasticsearch" + formatters: ["html"] ] end - defp description() do - "Ecto-friendly Elasticsearch dsl" - end - defp package() do [ + description: "Ecto-friendly Elasticsearch DSL", maintainers: ["Michael Guarino"], licenses: ["MIT"], - links: %{"GitHub" => "https://github.com/Frameio/exlasticsearch"} + links: %{ + "GitHub" => @source_url + } ] end end diff --git a/mix.lock b/mix.lock index 1a1d7b4..2713a56 100644 --- a/mix.lock +++ b/mix.lock @@ -3,21 +3,21 @@ "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "decorator": {:hex, :decorator, "1.4.0", "a57ac32c823ea7e4e67f5af56412d12b33274661bb7640ec7fc882f8d23ac419", [:mix], [], "hexpm", "0a07cedd9083da875c7418dea95b78361197cf2bf3211d743f6f7ce39656597f"}, "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm", "b42a23e9bd92d65d16db2f75553982e58519054095356a418bb8320bbacb58b1"}, - "earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.19", "de0d033d5ff9fc396a24eadc2fcf2afa3d120841eb3f1004d138cbf9273210e8", [:mix], [], "hexpm", "527ab6630b5c75c3a3960b75844c314ec305c76d9899bb30f71cb85952a9dc45"}, "ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"}, "elastix": {:hex, :elastix, "0.10.0", "7567da885677ba9deffc20063db5f3ca8cd10f23cff1ab3ed9c52b7063b7e340", [:mix], [{:httpoison, "~> 1.4", [hex: :httpoison, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0", [hex: :poison, repo: "hexpm", optional: true]}, {:retry, "~> 0.8", [hex: :retry, repo: "hexpm", optional: false]}], "hexpm", "5fb342ce068b20f7845f5dd198c2dc80d967deafaa940a6e51b846db82696d1d"}, - "ex_doc": {:hex, :ex_doc, "0.19.3", "3c7b0f02851f5fc13b040e8e925051452e41248f685e40250d7e40b07b9f8c10", [:mix], [{:earmark, "~> 1.2", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.10", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "0e11d67e662142fc3945b0ee410c73c8c956717fbeae4ad954b418747c734973"}, + "ex_doc": {:hex, :ex_doc, "0.28.0", "7eaf526dd8c80ae8c04d52ac8801594426ae322b52a6156cd038f30bafa8226f", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "e55cdadf69a5d1f4cfd8477122ebac5e1fadd433a8c1022dafc5025e48db0131"}, "flow": {:hex, :flow, "1.1.0", "b569c1042cb2da97103f6d70a0267a5657dce1402f41b4020bef98bbef9c7c1e", [:mix], [{:gen_stage, "~> 1.0", [hex: :gen_stage, repo: "hexpm", optional: false]}], "hexpm", "066f42f7a1ea6a86cb4ef763310338981a5cfb93bcebce10863a23a4859fd785"}, "gen_stage": {:hex, :gen_stage, "1.1.0", "dd0c0f8d2f3b993fdbd3d58e94abbe65380f4e78bdee3fa93d5618d7d14abe60", [:mix], [], "hexpm", "7f2b36a6d02f7ef2ba410733b540ec423af65ec9c99f3d1083da508aca3b9305"}, "hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"}, "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, - "makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.15.2", "dc72dfe17eb240552857465cc00cce390960d9a0c055c4ccd38b70629227e97c", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "fd23ae48d09b32eff49d4ced2b43c9f086d402ee4fd4fcb2d7fad97fa8823e75"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.1", "264fc6864936b59fedb3ceb89998c64e9bb91945faf1eb115d349b96913cc2ef", [:mix], [], "hexpm", "23c31d0ec38c97bf9adde35bc91bc8e1181ea5202881f48a192f4aa2d2cf4d59"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"},