mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
use elastic multi search API for specific pages
This commit is contained in:
parent
3fce31b658
commit
75de5f867d
6 changed files with 117 additions and 50 deletions
|
@ -183,6 +183,26 @@ defmodule Philomena.Elasticsearch do
|
|||
results
|
||||
end
|
||||
|
||||
def msearch(definitions) do
|
||||
msearch_body =
|
||||
Enum.flat_map(definitions, fn def ->
|
||||
[
|
||||
%{index: index_for(def.module).index_name()},
|
||||
def.body
|
||||
]
|
||||
end)
|
||||
|
||||
{:ok, %{body: results, status_code: 200}} =
|
||||
Elastix.Search.search(
|
||||
elastic_url(),
|
||||
"_all",
|
||||
[],
|
||||
msearch_body
|
||||
)
|
||||
|
||||
results["responses"]
|
||||
end
|
||||
|
||||
def search_definition(module, elastic_query, pagination_params \\ %{}) do
|
||||
page_number = pagination_params[:page_number] || 1
|
||||
page_size = pagination_params[:page_size] || 25
|
||||
|
@ -203,8 +223,7 @@ defmodule Philomena.Elasticsearch do
|
|||
}
|
||||
end
|
||||
|
||||
def search_results(definition) do
|
||||
results = search(definition.module, definition.body)
|
||||
defp process_results(results, definition) do
|
||||
time = results["took"]
|
||||
count = results["hits"]["total"]["value"]
|
||||
entries = Enum.map(results["hits"]["hits"], &{String.to_integer(&1["_id"]), &1})
|
||||
|
@ -221,6 +240,16 @@ defmodule Philomena.Elasticsearch do
|
|||
}
|
||||
end
|
||||
|
||||
def search_results(definition) do
|
||||
process_results(search(definition.module, definition.body), definition)
|
||||
end
|
||||
|
||||
def msearch_results(definitions) do
|
||||
Enum.map(Enum.zip(msearch(definitions), definitions), fn {result, definition} ->
|
||||
process_results(result, definition)
|
||||
end)
|
||||
end
|
||||
|
||||
defp load_records_from_results(results, ecto_queries) do
|
||||
Enum.map(Enum.zip(results, ecto_queries), fn {page, ecto_query} ->
|
||||
{ids, hits} = Enum.unzip(page.entries)
|
||||
|
@ -241,10 +270,22 @@ defmodule Philomena.Elasticsearch do
|
|||
page
|
||||
end
|
||||
|
||||
def msearch_records_with_hits(definitions, ecto_queries) do
|
||||
load_records_from_results(msearch_results(definitions), ecto_queries)
|
||||
end
|
||||
|
||||
def search_records(definition, ecto_query) do
|
||||
page = search_records_with_hits(definition, ecto_query)
|
||||
{records, _hits} = Enum.unzip(page.entries)
|
||||
|
||||
%{page | entries: records}
|
||||
end
|
||||
|
||||
def msearch_records(definitions, ecto_queries) do
|
||||
Enum.map(load_records_from_results(msearch_results(definitions), ecto_queries), fn page ->
|
||||
{records, _hits} = Enum.unzip(page.entries)
|
||||
|
||||
%{page | entries: records}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,12 +35,9 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
pagination: %{page_number: :rand.uniform(6), page_size: 4}
|
||||
)
|
||||
|
||||
images = Elasticsearch.search_records(images, preload(Image, :tags))
|
||||
top_scoring = Elasticsearch.search_records(top_scoring, preload(Image, :tags))
|
||||
|
||||
comments =
|
||||
Comment
|
||||
|> Elasticsearch.search_definition(
|
||||
Elasticsearch.search_definition(
|
||||
Comment,
|
||||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
|
@ -57,7 +54,6 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
},
|
||||
%{page_number: 1, page_size: 6}
|
||||
)
|
||||
|> Elasticsearch.search_records(preload(Comment, [:user, image: [:tags]]))
|
||||
|
||||
watched =
|
||||
if !!user do
|
||||
|
@ -68,11 +64,12 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
pagination: %{conn.assigns.image_pagination | page_number: 1}
|
||||
)
|
||||
|
||||
watched_images = Elasticsearch.search_records(watched_images, preload(Image, :tags))
|
||||
|
||||
if Enum.any?(watched_images), do: watched_images
|
||||
watched_images
|
||||
end
|
||||
|
||||
[images, top_scoring, comments, watched] =
|
||||
multi_search(images, top_scoring, comments, watched)
|
||||
|
||||
featured_image =
|
||||
Image
|
||||
|> join(:inner, [i], f in ImageFeature, on: [image_id: i.id])
|
||||
|
@ -142,4 +139,26 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
)
|
||||
)
|
||||
end
|
||||
|
||||
defp multi_search(images, top_scoring, comments, nil) do
|
||||
responses =
|
||||
Elasticsearch.msearch_records(
|
||||
[images, top_scoring, comments],
|
||||
[preload(Image, :tags), preload(Image, :tags), preload(Comment, [:user, image: :tags])]
|
||||
)
|
||||
|
||||
responses ++ [nil]
|
||||
end
|
||||
|
||||
defp multi_search(images, top_scoring, comments, watched) do
|
||||
Elasticsearch.msearch_records(
|
||||
[images, top_scoring, comments, watched],
|
||||
[
|
||||
preload(Image, :tags),
|
||||
preload(Image, :tags),
|
||||
preload(Comment, [:user, image: :tags]),
|
||||
preload(Image, :tags)
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,21 +53,22 @@ defmodule PhilomenaWeb.GalleryController do
|
|||
"sd" => position_order(gallery)
|
||||
})
|
||||
|
||||
conn = %{conn | params: params}
|
||||
|
||||
{:ok, {images, _tags}} = ImageLoader.search_string(conn, query)
|
||||
images = Elasticsearch.search_records_with_hits(images, preload(Image, :tags))
|
||||
|
||||
{gallery_prev, gallery_next} = prev_next_page_images(conn, query)
|
||||
|
||||
[images, gallery_prev, gallery_next] =
|
||||
Elasticsearch.msearch_records_with_hits(
|
||||
[images, gallery_prev, gallery_next],
|
||||
[preload(Image, :tags), preload(Image, :tags), preload(Image, :tags)]
|
||||
)
|
||||
|
||||
interactions = Interactions.user_interactions([images, gallery_prev, gallery_next], user)
|
||||
|
||||
watching = Galleries.subscribed?(gallery, user)
|
||||
|
||||
prev_image = if gallery_prev, do: [gallery_prev], else: []
|
||||
next_image = if gallery_next, do: [gallery_next], else: []
|
||||
gallery_images =
|
||||
Enum.to_list(gallery_prev) ++ Enum.to_list(images) ++ Enum.to_list(gallery_next)
|
||||
|
||||
gallery_images = prev_image ++ Enum.to_list(images) ++ next_image
|
||||
gallery_json = Jason.encode!(Enum.map(gallery_images, &elem(&1, 0).id))
|
||||
|
||||
Galleries.clear_notification(gallery, user)
|
||||
|
@ -81,8 +82,8 @@ defmodule PhilomenaWeb.GalleryController do
|
|||
layout_class: "layout--wide",
|
||||
watching: watching,
|
||||
gallery: gallery,
|
||||
gallery_prev: gallery_prev,
|
||||
gallery_next: gallery_next,
|
||||
gallery_prev: Enum.any?(gallery_prev),
|
||||
gallery_next: Enum.any?(gallery_next),
|
||||
gallery_images: gallery_images,
|
||||
images: images,
|
||||
interactions: interactions
|
||||
|
@ -159,20 +160,16 @@ defmodule PhilomenaWeb.GalleryController do
|
|||
{prev_image, next_image}
|
||||
end
|
||||
|
||||
defp gallery_image(offset, _conn, _query) when offset < 0, do: nil
|
||||
defp gallery_image(offset, _conn, _query) when offset < 0 do
|
||||
Elasticsearch.search_definition(Image, %{query: %{match_none: %{}}})
|
||||
end
|
||||
|
||||
defp gallery_image(offset, conn, query) do
|
||||
pagination_params = %{page_number: offset + 1, page_size: 1}
|
||||
|
||||
{:ok, {image, _tags}} =
|
||||
ImageLoader.search_string(conn, query, pagination: pagination_params)
|
||||
{:ok, {image, _tags}} = ImageLoader.search_string(conn, query, pagination: pagination_params)
|
||||
|
||||
image = Elasticsearch.search_records_with_hits(image, preload(Image, :tags))
|
||||
|
||||
case Enum.to_list(image) do
|
||||
[image] -> image
|
||||
[] -> nil
|
||||
end
|
||||
image
|
||||
end
|
||||
|
||||
defp parse_search(%{"gallery" => gallery_params}) do
|
||||
|
|
|
@ -53,9 +53,6 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
pagination: %{page_number: 1, page_size: 4}
|
||||
)
|
||||
|
||||
recent_uploads = Elasticsearch.search_records(recent_uploads, preload(Image, :tags))
|
||||
recent_faves = Elasticsearch.search_records(recent_faves, preload(Image, :tags))
|
||||
|
||||
tags = tags(conn.assigns.user.public_links)
|
||||
|
||||
all_tag_ids =
|
||||
|
@ -78,8 +75,8 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
recent_artwork = recent_artwork(conn, tags)
|
||||
|
||||
recent_comments =
|
||||
Comment
|
||||
|> Elasticsearch.search_definition(
|
||||
Elasticsearch.search_definition(
|
||||
Comment,
|
||||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
|
@ -97,17 +94,10 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
},
|
||||
%{page_size: 3}
|
||||
)
|
||||
|> Elasticsearch.search_records(preload(Comment, user: [awards: :badge], image: :tags))
|
||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.image))
|
||||
|
||||
recent_comments =
|
||||
recent_comments
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.zip(recent_comments)
|
||||
|
||||
recent_posts =
|
||||
Post
|
||||
|> Elasticsearch.search_definition(
|
||||
Elasticsearch.search_definition(
|
||||
Post,
|
||||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
|
@ -123,8 +113,26 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
},
|
||||
%{page_size: 6}
|
||||
)
|
||||
|> Elasticsearch.search_records(preload(Post, user: [awards: :badge], topic: :forum))
|
||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.topic))
|
||||
|
||||
[recent_uploads, recent_faves, recent_artwork, recent_comments, recent_posts] =
|
||||
Elasticsearch.msearch_records(
|
||||
[recent_uploads, recent_faves, recent_artwork, recent_comments, recent_posts],
|
||||
[
|
||||
preload(Image, :tags),
|
||||
preload(Image, :tags),
|
||||
preload(Image, :tags),
|
||||
preload(Comment, user: [awards: :badge], image: :tags),
|
||||
preload(Post, user: [awards: :badge], topic: :forum)
|
||||
]
|
||||
)
|
||||
|
||||
recent_posts = Enum.filter(recent_posts, &Canada.Can.can?(current_user, :show, &1.topic))
|
||||
|
||||
recent_comments =
|
||||
recent_comments
|
||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.image))
|
||||
|> TextileRenderer.render_collection(conn)
|
||||
|> Enum.zip(recent_comments)
|
||||
|
||||
about_me = TextileRenderer.render_one(%{body: user.description || ""}, conn)
|
||||
|
||||
|
@ -214,7 +222,9 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
defp tags([]), do: []
|
||||
defp tags(links), do: Enum.map(links, & &1.tag) |> Enum.reject(&is_nil/1)
|
||||
|
||||
defp recent_artwork(_conn, []), do: []
|
||||
defp recent_artwork(_conn, []) do
|
||||
Elasticsearch.search_definition(Image, %{query: %{match_none: %{}}})
|
||||
end
|
||||
|
||||
defp recent_artwork(conn, tags) do
|
||||
{images, _tags} =
|
||||
|
@ -224,7 +234,7 @@ defmodule PhilomenaWeb.ProfileController do
|
|||
pagination: %{page_number: 1, page_size: 4}
|
||||
)
|
||||
|
||||
Elasticsearch.search_records(images, preload(Image, :tags))
|
||||
images
|
||||
end
|
||||
|
||||
defp set_admin_metadata(conn, _opts) do
|
||||
|
|
|
@ -51,7 +51,7 @@ h3 Visibility
|
|||
|
||||
h3 Associated tag
|
||||
= if @user_link.tag do
|
||||
p
|
||||
.tag-list
|
||||
= render PhilomenaWeb.TagView, "_tag.html", tag: @user_link.tag, conn: @conn
|
||||
- else
|
||||
p There is no tag associated with this link.
|
||||
|
|
|
@ -12,10 +12,10 @@ defmodule PhilomenaWeb.GalleryView do
|
|||
|> Enum.join(" ")
|
||||
end
|
||||
|
||||
def sortable_prev(list, nil), do: list
|
||||
def sortable_prev(list, false), do: list
|
||||
def sortable_prev(list, _), do: ["js-sortable-has-prev" | list]
|
||||
|
||||
def sortable_next(list, nil), do: list
|
||||
def sortable_next(list, false), do: list
|
||||
def sortable_next(list, _), do: ["js-sortable-has-next" | list]
|
||||
|
||||
def show_subscription_link?(%{id: id}, %{id: id}), do: false
|
||||
|
|
Loading…
Reference in a new issue