mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
More fully separate underlying search behavior from usage in application
This commit is contained in:
parent
566ba9d4c1
commit
9b204c908d
2 changed files with 86 additions and 56 deletions
55
lib/philomena/search_policy.ex
Normal file
55
lib/philomena/search_policy.ex
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
defmodule Philomena.SearchPolicy do
|
||||||
|
alias Philomena.Comments.Comment
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Posts.Post
|
||||||
|
alias Philomena.Reports.Report
|
||||||
|
alias Philomena.Tags.Tag
|
||||||
|
alias Philomena.Filters.Filter
|
||||||
|
|
||||||
|
alias Philomena.Comments.SearchIndex, as: CommentIndex
|
||||||
|
alias Philomena.Galleries.SearchIndex, as: GalleryIndex
|
||||||
|
alias Philomena.Images.SearchIndex, as: ImageIndex
|
||||||
|
alias Philomena.Posts.SearchIndex, as: PostIndex
|
||||||
|
alias Philomena.Reports.SearchIndex, as: ReportIndex
|
||||||
|
alias Philomena.Tags.SearchIndex, as: TagIndex
|
||||||
|
alias Philomena.Filters.SearchIndex, as: FilterIndex
|
||||||
|
|
||||||
|
@type schema_module :: Comment | Gallery | Image | Post | Report | Tag | Filter
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
For a given schema module (e.g. `m:Philomena.Images.Image`), return the associated module
|
||||||
|
which implements the `SearchIndex` behaviour (e.g. `m:Philomena.Images.SearchIndex`).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
iex> SearchPolicy.index_for(Gallery)
|
||||||
|
Philomena.Galleries.SearchIndex
|
||||||
|
|
||||||
|
iex> SearchPolicy.index_for(:foo)
|
||||||
|
** (FunctionClauseError) no function clause matching in Philomena.SearchPolicy.index_for/1
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec index_for(schema_module()) :: module()
|
||||||
|
def index_for(Comment), do: CommentIndex
|
||||||
|
def index_for(Gallery), do: GalleryIndex
|
||||||
|
def index_for(Image), do: ImageIndex
|
||||||
|
def index_for(Post), do: PostIndex
|
||||||
|
def index_for(Report), do: ReportIndex
|
||||||
|
def index_for(Tag), do: TagIndex
|
||||||
|
def index_for(Filter), do: FilterIndex
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Return the path used to interact with the search engine.
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
iex> SearchPolicy.opensearch_url()
|
||||||
|
"http://localhost:9200"
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec opensearch_url :: String.t()
|
||||||
|
def opensearch_url do
|
||||||
|
Application.get_env(:philomena, :opensearch_url)
|
||||||
|
end
|
||||||
|
end
|
|
@ -15,35 +15,10 @@ defmodule PhilomenaQuery.Search do
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
import Elastix.HTTP
|
import Elastix.HTTP
|
||||||
|
|
||||||
alias Philomena.Comments.Comment
|
# todo: fetch through compile_env?
|
||||||
alias Philomena.Galleries.Gallery
|
@policy Philomena.SearchPolicy
|
||||||
alias Philomena.Images.Image
|
|
||||||
alias Philomena.Posts.Post
|
|
||||||
alias Philomena.Reports.Report
|
|
||||||
alias Philomena.Tags.Tag
|
|
||||||
alias Philomena.Filters.Filter
|
|
||||||
|
|
||||||
alias Philomena.Comments.SearchIndex, as: CommentIndex
|
@type schema_module :: @policy.schema_module()
|
||||||
alias Philomena.Galleries.SearchIndex, as: GalleryIndex
|
|
||||||
alias Philomena.Images.SearchIndex, as: ImageIndex
|
|
||||||
alias Philomena.Posts.SearchIndex, as: PostIndex
|
|
||||||
alias Philomena.Reports.SearchIndex, as: ReportIndex
|
|
||||||
alias Philomena.Tags.SearchIndex, as: TagIndex
|
|
||||||
alias Philomena.Filters.SearchIndex, as: FilterIndex
|
|
||||||
|
|
||||||
defp index_for(Comment), do: CommentIndex
|
|
||||||
defp index_for(Gallery), do: GalleryIndex
|
|
||||||
defp index_for(Image), do: ImageIndex
|
|
||||||
defp index_for(Post), do: PostIndex
|
|
||||||
defp index_for(Report), do: ReportIndex
|
|
||||||
defp index_for(Tag), do: TagIndex
|
|
||||||
defp index_for(Filter), do: FilterIndex
|
|
||||||
|
|
||||||
defp opensearch_url do
|
|
||||||
Application.get_env(:philomena, :opensearch_url)
|
|
||||||
end
|
|
||||||
|
|
||||||
@type index_module :: module()
|
|
||||||
@type queryable :: any()
|
@type queryable :: any()
|
||||||
@type query_body :: map()
|
@type query_body :: map()
|
||||||
|
|
||||||
|
@ -54,7 +29,7 @@ defmodule PhilomenaQuery.Search do
|
||||||
}
|
}
|
||||||
|
|
||||||
@type search_definition :: %{
|
@type search_definition :: %{
|
||||||
module: index_module(),
|
module: schema_module(),
|
||||||
body: query_body(),
|
body: query_body(),
|
||||||
page_number: integer(),
|
page_number: integer(),
|
||||||
page_size: integer()
|
page_size: integer()
|
||||||
|
@ -80,12 +55,12 @@ defmodule PhilomenaQuery.Search do
|
||||||
iex> Search.create_index!(Image)
|
iex> Search.create_index!(Image)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec create_index!(index_module()) :: any()
|
@spec create_index!(schema_module()) :: any()
|
||||||
def create_index!(module) do
|
def create_index!(module) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
Elastix.Index.create(
|
Elastix.Index.create(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
index.index_name(),
|
index.index_name(),
|
||||||
index.mapping()
|
index.mapping()
|
||||||
)
|
)
|
||||||
|
@ -104,11 +79,11 @@ defmodule PhilomenaQuery.Search do
|
||||||
iex> Search.delete_index!(Image)
|
iex> Search.delete_index!(Image)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec delete_index!(index_module()) :: any()
|
@spec delete_index!(schema_module()) :: any()
|
||||||
def delete_index!(module) do
|
def delete_index!(module) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
Elastix.Index.delete(opensearch_url(), index.index_name())
|
Elastix.Index.delete(@policy.opensearch_url(), index.index_name())
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc ~S"""
|
@doc ~S"""
|
||||||
|
@ -124,14 +99,14 @@ defmodule PhilomenaQuery.Search do
|
||||||
iex> Search.update_mapping!(Image)
|
iex> Search.update_mapping!(Image)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec update_mapping!(index_module()) :: any()
|
@spec update_mapping!(schema_module()) :: any()
|
||||||
def update_mapping!(module) do
|
def update_mapping!(module) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
index_name = index.index_name()
|
index_name = index.index_name()
|
||||||
mapping = index.mapping().mappings.properties
|
mapping = index.mapping().mappings.properties
|
||||||
|
|
||||||
Elastix.Mapping.put(opensearch_url(), index_name, "_doc", %{properties: mapping},
|
Elastix.Mapping.put(@policy.opensearch_url(), index_name, "_doc", %{properties: mapping},
|
||||||
include_type_name: true
|
include_type_name: true
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -151,13 +126,13 @@ defmodule PhilomenaQuery.Search do
|
||||||
iex> Search.index_document(%Image{...}, Image)
|
iex> Search.index_document(%Image{...}, Image)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec index_document(struct(), index_module()) :: any()
|
@spec index_document(struct(), schema_module()) :: any()
|
||||||
def index_document(doc, module) do
|
def index_document(doc, module) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
data = index.as_json(doc)
|
data = index.as_json(doc)
|
||||||
|
|
||||||
Elastix.Document.index(
|
Elastix.Document.index(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
index.index_name(),
|
index.index_name(),
|
||||||
"_doc",
|
"_doc",
|
||||||
data.id,
|
data.id,
|
||||||
|
@ -181,12 +156,12 @@ defmodule PhilomenaQuery.Search do
|
||||||
iex> Search.delete_document(image.id, Image)
|
iex> Search.delete_document(image.id, Image)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec delete_document(term(), index_module()) :: any()
|
@spec delete_document(term(), schema_module()) :: any()
|
||||||
def delete_document(id, module) do
|
def delete_document(id, module) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
Elastix.Document.delete(
|
Elastix.Document.delete(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
index.index_name(),
|
index.index_name(),
|
||||||
"_doc",
|
"_doc",
|
||||||
id
|
id
|
||||||
|
@ -215,9 +190,9 @@ defmodule PhilomenaQuery.Search do
|
||||||
Search.reindex(query, Image, batch_size: 5000)
|
Search.reindex(query, Image, batch_size: 5000)
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec reindex(queryable(), index_module(), Batch.batch_options()) :: []
|
@spec reindex(queryable(), schema_module(), Batch.batch_options()) :: []
|
||||||
def reindex(queryable, module, opts \\ []) do
|
def reindex(queryable, module, opts \\ []) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
Batch.record_batches(queryable, opts, fn records ->
|
Batch.record_batches(queryable, opts, fn records ->
|
||||||
lines =
|
lines =
|
||||||
|
@ -231,7 +206,7 @@ defmodule PhilomenaQuery.Search do
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Elastix.Bulk.post(
|
Elastix.Bulk.post(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
lines,
|
lines,
|
||||||
index: index.index_name(),
|
index: index.index_name(),
|
||||||
httpoison_options: [timeout: 30_000]
|
httpoison_options: [timeout: 30_000]
|
||||||
|
@ -267,12 +242,12 @@ defmodule PhilomenaQuery.Search do
|
||||||
Search.update_by_query(Post, query_body, [set_replacement], [])
|
Search.update_by_query(Post, query_body, [set_replacement], [])
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec update_by_query(index_module(), query_body(), [replacement()], [replacement()]) :: any()
|
@spec update_by_query(schema_module(), query_body(), [replacement()], [replacement()]) :: any()
|
||||||
def update_by_query(module, query_body, set_replacements, replacements) do
|
def update_by_query(module, query_body, set_replacements, replacements) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
url =
|
url =
|
||||||
opensearch_url()
|
@policy.opensearch_url()
|
||||||
|> prepare_url([index.index_name(), "_update_by_query"])
|
|> prepare_url([index.index_name(), "_update_by_query"])
|
||||||
|> append_query_string(%{conflicts: "proceed", wait_for_completion: "false"})
|
|> append_query_string(%{conflicts: "proceed", wait_for_completion: "false"})
|
||||||
|
|
||||||
|
@ -355,13 +330,13 @@ defmodule PhilomenaQuery.Search do
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec search(index_module(), query_body()) :: map()
|
@spec search(schema_module(), query_body()) :: map()
|
||||||
def search(module, query_body) do
|
def search(module, query_body) do
|
||||||
index = index_for(module)
|
index = @policy.index_for(module)
|
||||||
|
|
||||||
{:ok, %{body: results, status_code: 200}} =
|
{:ok, %{body: results, status_code: 200}} =
|
||||||
Elastix.Search.search(
|
Elastix.Search.search(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
index.index_name(),
|
index.index_name(),
|
||||||
[],
|
[],
|
||||||
query_body
|
query_body
|
||||||
|
@ -395,14 +370,14 @@ defmodule PhilomenaQuery.Search do
|
||||||
msearch_body =
|
msearch_body =
|
||||||
Enum.flat_map(definitions, fn def ->
|
Enum.flat_map(definitions, fn def ->
|
||||||
[
|
[
|
||||||
%{index: index_for(def.module).index_name()},
|
%{index: @policy.index_for(def.module).index_name()},
|
||||||
def.body
|
def.body
|
||||||
]
|
]
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{:ok, %{body: results, status_code: 200}} =
|
{:ok, %{body: results, status_code: 200}} =
|
||||||
Elastix.Search.search(
|
Elastix.Search.search(
|
||||||
opensearch_url(),
|
@policy.opensearch_url(),
|
||||||
"_all",
|
"_all",
|
||||||
[],
|
[],
|
||||||
msearch_body
|
msearch_body
|
||||||
|
@ -440,7 +415,7 @@ defmodule PhilomenaQuery.Search do
|
||||||
}
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@spec search_definition(index_module(), query_body(), pagination_params()) ::
|
@spec search_definition(schema_module(), query_body(), pagination_params()) ::
|
||||||
search_definition()
|
search_definition()
|
||||||
def search_definition(module, search_query, pagination_params \\ %{}) do
|
def search_definition(module, search_query, pagination_params \\ %{}) do
|
||||||
page_number = pagination_params[:page_number] || 1
|
page_number = pagination_params[:page_number] || 1
|
||||||
|
|
Loading…
Reference in a new issue