mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +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
|
results
|
||||||
end
|
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
|
def search_definition(module, elastic_query, pagination_params \\ %{}) do
|
||||||
page_number = pagination_params[:page_number] || 1
|
page_number = pagination_params[:page_number] || 1
|
||||||
page_size = pagination_params[:page_size] || 25
|
page_size = pagination_params[:page_size] || 25
|
||||||
|
@ -203,8 +223,7 @@ defmodule Philomena.Elasticsearch do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_results(definition) do
|
defp process_results(results, definition) do
|
||||||
results = search(definition.module, definition.body)
|
|
||||||
time = results["took"]
|
time = results["took"]
|
||||||
count = results["hits"]["total"]["value"]
|
count = results["hits"]["total"]["value"]
|
||||||
entries = Enum.map(results["hits"]["hits"], &{String.to_integer(&1["_id"]), &1})
|
entries = Enum.map(results["hits"]["hits"], &{String.to_integer(&1["_id"]), &1})
|
||||||
|
@ -221,6 +240,16 @@ defmodule Philomena.Elasticsearch do
|
||||||
}
|
}
|
||||||
end
|
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
|
defp load_records_from_results(results, ecto_queries) do
|
||||||
Enum.map(Enum.zip(results, ecto_queries), fn {page, ecto_query} ->
|
Enum.map(Enum.zip(results, ecto_queries), fn {page, ecto_query} ->
|
||||||
{ids, hits} = Enum.unzip(page.entries)
|
{ids, hits} = Enum.unzip(page.entries)
|
||||||
|
@ -241,10 +270,22 @@ defmodule Philomena.Elasticsearch do
|
||||||
page
|
page
|
||||||
end
|
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
|
def search_records(definition, ecto_query) do
|
||||||
page = search_records_with_hits(definition, ecto_query)
|
page = search_records_with_hits(definition, ecto_query)
|
||||||
{records, _hits} = Enum.unzip(page.entries)
|
{records, _hits} = Enum.unzip(page.entries)
|
||||||
|
|
||||||
%{page | entries: records}
|
%{page | entries: records}
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -35,12 +35,9 @@ defmodule PhilomenaWeb.ActivityController do
|
||||||
pagination: %{page_number: :rand.uniform(6), page_size: 4}
|
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 =
|
comments =
|
||||||
Comment
|
Elasticsearch.search_definition(
|
||||||
|> Elasticsearch.search_definition(
|
Comment,
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -57,7 +54,6 @@ defmodule PhilomenaWeb.ActivityController do
|
||||||
},
|
},
|
||||||
%{page_number: 1, page_size: 6}
|
%{page_number: 1, page_size: 6}
|
||||||
)
|
)
|
||||||
|> Elasticsearch.search_records(preload(Comment, [:user, image: [:tags]]))
|
|
||||||
|
|
||||||
watched =
|
watched =
|
||||||
if !!user do
|
if !!user do
|
||||||
|
@ -68,11 +64,12 @@ defmodule PhilomenaWeb.ActivityController do
|
||||||
pagination: %{conn.assigns.image_pagination | page_number: 1}
|
pagination: %{conn.assigns.image_pagination | page_number: 1}
|
||||||
)
|
)
|
||||||
|
|
||||||
watched_images = Elasticsearch.search_records(watched_images, preload(Image, :tags))
|
watched_images
|
||||||
|
|
||||||
if Enum.any?(watched_images), do: watched_images
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
[images, top_scoring, comments, watched] =
|
||||||
|
multi_search(images, top_scoring, comments, watched)
|
||||||
|
|
||||||
featured_image =
|
featured_image =
|
||||||
Image
|
Image
|
||||||
|> join(:inner, [i], f in ImageFeature, on: [image_id: i.id])
|
|> join(:inner, [i], f in ImageFeature, on: [image_id: i.id])
|
||||||
|
@ -142,4 +139,26 @@ defmodule PhilomenaWeb.ActivityController do
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -53,21 +53,22 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
"sd" => position_order(gallery)
|
"sd" => position_order(gallery)
|
||||||
})
|
})
|
||||||
|
|
||||||
conn = %{conn | params: params}
|
|
||||||
|
|
||||||
{:ok, {images, _tags}} = ImageLoader.search_string(conn, query)
|
{: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)
|
{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)
|
interactions = Interactions.user_interactions([images, gallery_prev, gallery_next], user)
|
||||||
|
|
||||||
watching = Galleries.subscribed?(gallery, user)
|
watching = Galleries.subscribed?(gallery, user)
|
||||||
|
|
||||||
prev_image = if gallery_prev, do: [gallery_prev], else: []
|
gallery_images =
|
||||||
next_image = if gallery_next, do: [gallery_next], else: []
|
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))
|
gallery_json = Jason.encode!(Enum.map(gallery_images, &elem(&1, 0).id))
|
||||||
|
|
||||||
Galleries.clear_notification(gallery, user)
|
Galleries.clear_notification(gallery, user)
|
||||||
|
@ -81,8 +82,8 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
layout_class: "layout--wide",
|
layout_class: "layout--wide",
|
||||||
watching: watching,
|
watching: watching,
|
||||||
gallery: gallery,
|
gallery: gallery,
|
||||||
gallery_prev: gallery_prev,
|
gallery_prev: Enum.any?(gallery_prev),
|
||||||
gallery_next: gallery_next,
|
gallery_next: Enum.any?(gallery_next),
|
||||||
gallery_images: gallery_images,
|
gallery_images: gallery_images,
|
||||||
images: images,
|
images: images,
|
||||||
interactions: interactions
|
interactions: interactions
|
||||||
|
@ -159,20 +160,16 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
{prev_image, next_image}
|
{prev_image, next_image}
|
||||||
end
|
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
|
defp gallery_image(offset, conn, query) do
|
||||||
pagination_params = %{page_number: offset + 1, page_size: 1}
|
pagination_params = %{page_number: offset + 1, page_size: 1}
|
||||||
|
|
||||||
{:ok, {image, _tags}} =
|
{:ok, {image, _tags}} = ImageLoader.search_string(conn, query, pagination: pagination_params)
|
||||||
ImageLoader.search_string(conn, query, pagination: pagination_params)
|
|
||||||
|
|
||||||
image = Elasticsearch.search_records_with_hits(image, preload(Image, :tags))
|
image
|
||||||
|
|
||||||
case Enum.to_list(image) do
|
|
||||||
[image] -> image
|
|
||||||
[] -> nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
defp parse_search(%{"gallery" => gallery_params}) do
|
defp parse_search(%{"gallery" => gallery_params}) do
|
||||||
|
|
|
@ -53,9 +53,6 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
pagination: %{page_number: 1, page_size: 4}
|
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)
|
tags = tags(conn.assigns.user.public_links)
|
||||||
|
|
||||||
all_tag_ids =
|
all_tag_ids =
|
||||||
|
@ -78,8 +75,8 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
recent_artwork = recent_artwork(conn, tags)
|
recent_artwork = recent_artwork(conn, tags)
|
||||||
|
|
||||||
recent_comments =
|
recent_comments =
|
||||||
Comment
|
Elasticsearch.search_definition(
|
||||||
|> Elasticsearch.search_definition(
|
Comment,
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -97,17 +94,10 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
},
|
},
|
||||||
%{page_size: 3}
|
%{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 =
|
recent_posts =
|
||||||
Post
|
Elasticsearch.search_definition(
|
||||||
|> Elasticsearch.search_definition(
|
Post,
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -123,8 +113,26 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
},
|
},
|
||||||
%{page_size: 6}
|
%{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)
|
about_me = TextileRenderer.render_one(%{body: user.description || ""}, conn)
|
||||||
|
|
||||||
|
@ -214,7 +222,9 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
defp tags([]), do: []
|
defp tags([]), do: []
|
||||||
defp tags(links), do: Enum.map(links, & &1.tag) |> Enum.reject(&is_nil/1)
|
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
|
defp recent_artwork(conn, tags) do
|
||||||
{images, _tags} =
|
{images, _tags} =
|
||||||
|
@ -224,7 +234,7 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
pagination: %{page_number: 1, page_size: 4}
|
pagination: %{page_number: 1, page_size: 4}
|
||||||
)
|
)
|
||||||
|
|
||||||
Elasticsearch.search_records(images, preload(Image, :tags))
|
images
|
||||||
end
|
end
|
||||||
|
|
||||||
defp set_admin_metadata(conn, _opts) do
|
defp set_admin_metadata(conn, _opts) do
|
||||||
|
|
|
@ -51,7 +51,7 @@ h3 Visibility
|
||||||
|
|
||||||
h3 Associated tag
|
h3 Associated tag
|
||||||
= if @user_link.tag do
|
= if @user_link.tag do
|
||||||
p
|
.tag-list
|
||||||
= render PhilomenaWeb.TagView, "_tag.html", tag: @user_link.tag, conn: @conn
|
= render PhilomenaWeb.TagView, "_tag.html", tag: @user_link.tag, conn: @conn
|
||||||
- else
|
- else
|
||||||
p There is no tag associated with this link.
|
p There is no tag associated with this link.
|
||||||
|
|
|
@ -12,10 +12,10 @@ defmodule PhilomenaWeb.GalleryView do
|
||||||
|> Enum.join(" ")
|
|> Enum.join(" ")
|
||||||
end
|
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_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 sortable_next(list, _), do: ["js-sortable-has-next" | list]
|
||||||
|
|
||||||
def show_subscription_link?(%{id: id}, %{id: id}), do: false
|
def show_subscription_link?(%{id: id}, %{id: id}), do: false
|
||||||
|
|
Loading…
Reference in a new issue