mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-30 14:57:59 +01:00
separate search definition building from search execution
This commit is contained in:
parent
42d03ef548
commit
3fce31b658
23 changed files with 151 additions and 100 deletions
|
@ -183,7 +183,7 @@ defmodule Philomena.Elasticsearch do
|
||||||
results
|
results
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_results(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
|
||||||
|
|
||||||
|
@ -195,38 +195,54 @@ defmodule Philomena.Elasticsearch do
|
||||||
track_total_hits: true
|
track_total_hits: true
|
||||||
})
|
})
|
||||||
|
|
||||||
results = search(module, elastic_query)
|
%{
|
||||||
|
module: module,
|
||||||
|
body: elastic_query,
|
||||||
|
page_number: page_number,
|
||||||
|
page_size: page_size
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_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})
|
||||||
|
|
||||||
Logger.debug("[Elasticsearch] Query took #{time}ms")
|
Logger.debug("[Elasticsearch] Query took #{time}ms")
|
||||||
Logger.debug("[Elasticsearch] #{Jason.encode!(elastic_query)}")
|
Logger.debug("[Elasticsearch] #{Jason.encode!(definition.body)}")
|
||||||
|
|
||||||
%Scrivener.Page{
|
%Scrivener.Page{
|
||||||
entries: entries,
|
entries: entries,
|
||||||
page_number: page_number,
|
page_number: definition.page_number,
|
||||||
page_size: page_size,
|
page_size: definition.page_size,
|
||||||
total_entries: count,
|
total_entries: count,
|
||||||
total_pages: div(count + page_size - 1, page_size)
|
total_pages: div(count + definition.page_size - 1, definition.page_size)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_records_with_hits(module, elastic_query, pagination_params, ecto_query) do
|
defp load_records_from_results(results, ecto_queries) do
|
||||||
page = search_results(module, elastic_query, pagination_params)
|
Enum.map(Enum.zip(results, ecto_queries), fn {page, ecto_query} ->
|
||||||
{ids, hits} = Enum.unzip(page.entries)
|
{ids, hits} = Enum.unzip(page.entries)
|
||||||
|
|
||||||
records =
|
records =
|
||||||
ecto_query
|
ecto_query
|
||||||
|> where([m], m.id in ^ids)
|
|> where([m], m.id in ^ids)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|> Enum.sort_by(&Enum.find_index(ids, fn el -> el == &1.id end))
|
|> Enum.sort_by(&Enum.find_index(ids, fn el -> el == &1.id end))
|
||||||
|
|
||||||
%{page | entries: Enum.zip(records, hits)}
|
%{page | entries: Enum.zip(records, hits)}
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_records(module, elastic_query, pagination_params, ecto_query) do
|
def search_records_with_hits(definition, ecto_query) do
|
||||||
page = search_records_with_hits(module, elastic_query, pagination_params, ecto_query)
|
[page] = load_records_from_results([search_results(definition)], [ecto_query])
|
||||||
|
|
||||||
|
page
|
||||||
|
end
|
||||||
|
|
||||||
|
def search_records(definition, ecto_query) do
|
||||||
|
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}
|
||||||
|
|
|
@ -35,9 +35,12 @@ 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 =
|
||||||
Elasticsearch.search_records(
|
Comment
|
||||||
Comment,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -52,9 +55,9 @@ defmodule PhilomenaWeb.ActivityController do
|
||||||
},
|
},
|
||||||
sort: %{posted_at: :desc}
|
sort: %{posted_at: :desc}
|
||||||
},
|
},
|
||||||
%{page_number: 1, page_size: 6},
|
%{page_number: 1, page_size: 6}
|
||||||
Comment |> preload([:user, image: [:tags]])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Comment, [:user, image: [:tags]]))
|
||||||
|
|
||||||
watched =
|
watched =
|
||||||
if !!user do
|
if !!user do
|
||||||
|
@ -65,6 +68,8 @@ 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))
|
||||||
|
|
||||||
if Enum.any?(watched_images), do: watched_images
|
if Enum.any?(watched_images), do: watched_images
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -80,15 +80,15 @@ defmodule PhilomenaWeb.Admin.ReportController do
|
||||||
|
|
||||||
defp load_reports(conn, query) do
|
defp load_reports(conn, query) do
|
||||||
reports =
|
reports =
|
||||||
Elasticsearch.search_records(
|
Report
|
||||||
Report,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: query,
|
query: query,
|
||||||
sort: sorts()
|
sort: sorts()
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
Report |> preload([:admin, user: :linked_tags])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Report, [:admin, user: :linked_tags]))
|
||||||
|
|
||||||
entries = Polymorphic.load_polymorphic(reports, reportable: [reportable_id: :reportable_type])
|
entries = Polymorphic.load_polymorphic(reports, reportable: [reportable_id: :reportable_type])
|
||||||
|
|
||||||
|
|
|
@ -13,8 +13,8 @@ defmodule PhilomenaWeb.Api.Json.Search.CommentController do
|
||||||
case Query.compile(user, params["q"] || "") do
|
case Query.compile(user, params["q"] || "") do
|
||||||
{:ok, query} ->
|
{:ok, query} ->
|
||||||
comments =
|
comments =
|
||||||
Elasticsearch.search_records(
|
Comment
|
||||||
Comment,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -29,9 +29,9 @@ defmodule PhilomenaWeb.Api.Json.Search.CommentController do
|
||||||
},
|
},
|
||||||
sort: %{posted_at: :desc}
|
sort: %{posted_at: :desc}
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
preload(Comment, [:image, :user])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Comment, [:image, :user]))
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(PhilomenaWeb.Api.Json.CommentView)
|
|> put_view(PhilomenaWeb.Api.Json.CommentView)
|
||||||
|
|
|
@ -10,15 +10,15 @@ defmodule PhilomenaWeb.Api.Json.Search.GalleryController do
|
||||||
case Query.compile(params["q"] || "") do
|
case Query.compile(params["q"] || "") do
|
||||||
{:ok, query} ->
|
{:ok, query} ->
|
||||||
galleries =
|
galleries =
|
||||||
Elasticsearch.search_records(
|
Gallery
|
||||||
Gallery,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: query,
|
query: query,
|
||||||
sort: %{created_at: :desc}
|
sort: %{created_at: :desc}
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
preload(Gallery, [:creator])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Gallery, [:creator]))
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(PhilomenaWeb.Api.Json.GalleryView)
|
|> put_view(PhilomenaWeb.Api.Json.GalleryView)
|
||||||
|
|
|
@ -2,6 +2,7 @@ defmodule PhilomenaWeb.Api.Json.Search.ImageController do
|
||||||
use PhilomenaWeb, :controller
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
@ -10,8 +11,9 @@ defmodule PhilomenaWeb.Api.Json.Search.ImageController do
|
||||||
queryable = Image |> preload([:tags, :user, :intensity])
|
queryable = Image |> preload([:tags, :user, :intensity])
|
||||||
user = conn.assigns.current_user
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
case ImageLoader.search_string(conn, params["q"], queryable: queryable) do
|
case ImageLoader.search_string(conn, params["q"]) do
|
||||||
{:ok, {images, _tags}} ->
|
{:ok, {images, _tags}} ->
|
||||||
|
images = Elasticsearch.search_records(images, queryable)
|
||||||
interactions = Interactions.user_interactions(images, user)
|
interactions = Interactions.user_interactions(images, user)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -12,8 +12,8 @@ defmodule PhilomenaWeb.Api.Json.Search.PostController do
|
||||||
case Query.compile(user, params["q"] || "") do
|
case Query.compile(user, params["q"] || "") do
|
||||||
{:ok, query} ->
|
{:ok, query} ->
|
||||||
posts =
|
posts =
|
||||||
Elasticsearch.search_records(
|
Post
|
||||||
Post,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -26,9 +26,9 @@ defmodule PhilomenaWeb.Api.Json.Search.PostController do
|
||||||
},
|
},
|
||||||
sort: %{created_at: :desc}
|
sort: %{created_at: :desc}
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
preload(Post, [:user, :topic])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Post, [:user, :topic]))
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(PhilomenaWeb.Api.Json.Forum.Topic.PostView)
|
|> put_view(PhilomenaWeb.Api.Json.Forum.Topic.PostView)
|
||||||
|
|
|
@ -10,10 +10,12 @@ defmodule PhilomenaWeb.Api.Json.Search.TagController do
|
||||||
case Query.compile(params["q"] || "") do
|
case Query.compile(params["q"] || "") do
|
||||||
{:ok, query} ->
|
{:ok, query} ->
|
||||||
tags =
|
tags =
|
||||||
Elasticsearch.search_records(
|
Tag
|
||||||
Tag,
|
|> Elasticsearch.search_definition(
|
||||||
%{query: query, sort: %{images: :desc}},
|
%{query: query, sort: %{images: :desc}},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
|
)
|
||||||
|
|> Elasticsearch.search_records(
|
||||||
preload(Tag, [:aliased_tag, :aliases, :implied_tags, :implied_by_tags, :dnp_entries])
|
preload(Tag, [:aliased_tag, :aliases, :implied_tags, :implied_by_tags, :dnp_entries])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,14 @@ defmodule PhilomenaWeb.Api.Rss.WatchedController do
|
||||||
use PhilomenaWeb, :controller
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
|
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
def index(conn, _params) do
|
def index(conn, _params) do
|
||||||
{:ok, {images, _tags}} = ImageLoader.search_string(conn, "my:watched")
|
{:ok, {images, _tags}} = ImageLoader.search_string(conn, "my:watched")
|
||||||
|
images = Elasticsearch.search_records(images, preload(Image, :tags))
|
||||||
|
|
||||||
# NB: this is RSS, but using the RSS format causes Phoenix not to
|
# NB: this is RSS, but using the RSS format causes Phoenix not to
|
||||||
# escape HTML
|
# escape HTML
|
||||||
|
|
|
@ -20,8 +20,8 @@ defmodule PhilomenaWeb.CommentController do
|
||||||
|
|
||||||
defp render_index({:ok, query}, conn, user) do
|
defp render_index({:ok, query}, conn, user) do
|
||||||
comments =
|
comments =
|
||||||
Elasticsearch.search_records(
|
Comment
|
||||||
Comment,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -33,8 +33,10 @@ defmodule PhilomenaWeb.CommentController do
|
||||||
},
|
},
|
||||||
sort: %{posted_at: :desc}
|
sort: %{posted_at: :desc}
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
Comment |> preload([:deleted_by, image: [:tags], user: [awards: :badge]])
|
)
|
||||||
|
|> Elasticsearch.search_records(
|
||||||
|
preload(Comment, [:deleted_by, image: [:tags], user: [awards: :badge]])
|
||||||
)
|
)
|
||||||
|
|
||||||
rendered = TextileRenderer.render_collection(comments.entries, conn)
|
rendered = TextileRenderer.render_collection(comments.entries, conn)
|
||||||
|
|
|
@ -7,6 +7,7 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Galleries.Gallery
|
alias Philomena.Galleries.Gallery
|
||||||
alias Philomena.Galleries
|
alias Philomena.Galleries
|
||||||
|
alias Philomena.Images.Image
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create, :edit, :update, :delete]
|
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create, :edit, :update, :delete]
|
||||||
|
@ -19,8 +20,8 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
|
|
||||||
def index(conn, params) do
|
def index(conn, params) do
|
||||||
galleries =
|
galleries =
|
||||||
Elasticsearch.search_records(
|
Gallery
|
||||||
Gallery,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -29,9 +30,9 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
},
|
},
|
||||||
sort: parse_sort(params)
|
sort: parse_sort(params)
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
Gallery |> preload([:creator, thumbnail: :tags])
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Gallery, [:creator, thumbnail: :tags]))
|
||||||
|
|
||||||
render(conn, "index.html",
|
render(conn, "index.html",
|
||||||
title: "Galleries",
|
title: "Galleries",
|
||||||
|
@ -54,7 +55,8 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
|
|
||||||
conn = %{conn | params: params}
|
conn = %{conn | params: params}
|
||||||
|
|
||||||
{:ok, {images, _tags}} = ImageLoader.search_string(conn, query, include_hits: true)
|
{: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)
|
||||||
|
|
||||||
|
@ -163,7 +165,9 @@ defmodule PhilomenaWeb.GalleryController 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, include_hits: true)
|
ImageLoader.search_string(conn, query, pagination: pagination_params)
|
||||||
|
|
||||||
|
image = Elasticsearch.search_records_with_hits(image, preload(Image, :tags))
|
||||||
|
|
||||||
case Enum.to_list(image) do
|
case Enum.to_list(image) do
|
||||||
[image] -> image
|
[image] -> image
|
||||||
|
|
|
@ -4,6 +4,7 @@ defmodule PhilomenaWeb.Image.NavigateController do
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
alias PhilomenaWeb.ImageNavigator
|
alias PhilomenaWeb.ImageNavigator
|
||||||
alias PhilomenaWeb.ImageScope
|
alias PhilomenaWeb.ImageScope
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
alias Philomena.Images.Query
|
alias Philomena.Images.Query
|
||||||
|
|
||||||
|
@ -35,7 +36,8 @@ defmodule PhilomenaWeb.Image.NavigateController do
|
||||||
# (although it probably should).
|
# (although it probably should).
|
||||||
body = %{range: %{id: %{gt: conn.assigns.image.id}}}
|
body = %{range: %{id: %{gt: conn.assigns.image.id}}}
|
||||||
|
|
||||||
{images, _tags} = ImageLoader.query(conn, body, queryable: Image, pagination: pagination)
|
{images, _tags} = ImageLoader.query(conn, body, pagination: pagination)
|
||||||
|
images = Elasticsearch.search_records(images, Image)
|
||||||
|
|
||||||
page_num = page_for_offset(pagination.page_size, images.total_entries)
|
page_num = page_for_offset(pagination.page_size, images.total_entries)
|
||||||
|
|
||||||
|
|
|
@ -33,8 +33,8 @@ defmodule PhilomenaWeb.Image.RandomController do
|
||||||
defp random_image_id(query, filter) do
|
defp random_image_id(query, filter) do
|
||||||
%{query: query, sorts: sort} = ImageSorter.parse_sort(%{"sf" => "random"}, query)
|
%{query: query, sorts: sort} = ImageSorter.parse_sort(%{"sf" => "random"}, query)
|
||||||
|
|
||||||
Elasticsearch.search_records(
|
Image
|
||||||
Image,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -47,9 +47,9 @@ defmodule PhilomenaWeb.Image.RandomController do
|
||||||
},
|
},
|
||||||
sort: sort
|
sort: sort
|
||||||
},
|
},
|
||||||
%{page_size: 1},
|
%{page_size: 1}
|
||||||
Image
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(Image)
|
||||||
|> Enum.to_list()
|
|> Enum.to_list()
|
||||||
|> unwrap()
|
|> unwrap()
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,8 @@ defmodule PhilomenaWeb.Image.RelatedController do
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
plug PhilomenaWeb.CanaryMapPlug, index: :show
|
plug PhilomenaWeb.CanaryMapPlug, index: :show
|
||||||
|
|
||||||
|
@ -58,6 +60,8 @@ defmodule PhilomenaWeb.Image.RelatedController do
|
||||||
pagination: %{conn.assigns.image_pagination | page_number: 1}
|
pagination: %{conn.assigns.image_pagination | page_number: 1}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
images = Elasticsearch.search_records(images, preload(Image, :tags))
|
||||||
|
|
||||||
interactions = Interactions.user_interactions(images, user)
|
interactions = Interactions.user_interactions(images, user)
|
||||||
|
|
||||||
render(conn, "index.html",
|
render(conn, "index.html",
|
||||||
|
|
|
@ -13,6 +13,7 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
Galleries.Gallery
|
Galleries.Gallery
|
||||||
}
|
}
|
||||||
|
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Comments
|
alias Philomena.Comments
|
||||||
alias Philomena.Repo
|
alias Philomena.Repo
|
||||||
|
@ -36,6 +37,8 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
def index(conn, _params) do
|
def index(conn, _params) do
|
||||||
{:ok, {images, _tags}} = ImageLoader.search_string(conn, "created_at.lte:3 minutes ago")
|
{:ok, {images, _tags}} = ImageLoader.search_string(conn, "created_at.lte:3 minutes ago")
|
||||||
|
|
||||||
|
images = Elasticsearch.search_records(images, preload(Image, :tags))
|
||||||
|
|
||||||
interactions = Interactions.user_interactions(images, conn.assigns.current_user)
|
interactions = Interactions.user_interactions(images, conn.assigns.current_user)
|
||||||
|
|
||||||
render(conn, "index.html",
|
render(conn, "index.html",
|
||||||
|
|
|
@ -20,8 +20,8 @@ defmodule PhilomenaWeb.PostController do
|
||||||
|
|
||||||
defp render_index({:ok, query}, conn, user) do
|
defp render_index({:ok, query}, conn, user) do
|
||||||
posts =
|
posts =
|
||||||
Elasticsearch.search_records(
|
Post
|
||||||
Post,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -30,8 +30,10 @@ defmodule PhilomenaWeb.PostController do
|
||||||
},
|
},
|
||||||
sort: %{created_at: :desc}
|
sort: %{created_at: :desc}
|
||||||
},
|
},
|
||||||
conn.assigns.pagination,
|
conn.assigns.pagination
|
||||||
Post |> preload([:deleted_by, topic: :forum, user: [awards: :badge]])
|
)
|
||||||
|
|> Elasticsearch.search_records(
|
||||||
|
preload(Post, [:deleted_by, topic: :forum, user: [awards: :badge]])
|
||||||
)
|
)
|
||||||
|
|
||||||
rendered = TextileRenderer.render_collection(posts.entries, conn)
|
rendered = TextileRenderer.render_collection(posts.entries, conn)
|
||||||
|
|
|
@ -16,6 +16,7 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
alias Philomena.UserFingerprints.UserFingerprint
|
alias Philomena.UserFingerprints.UserFingerprint
|
||||||
alias Philomena.ModNotes.ModNote
|
alias Philomena.ModNotes.ModNote
|
||||||
alias Philomena.Polymorphic
|
alias Philomena.Polymorphic
|
||||||
|
alias Philomena.Images.Image
|
||||||
alias Philomena.Repo
|
alias Philomena.Repo
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
@ -52,6 +53,9 @@ 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 =
|
||||||
|
@ -74,8 +78,8 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
recent_artwork = recent_artwork(conn, tags)
|
recent_artwork = recent_artwork(conn, tags)
|
||||||
|
|
||||||
recent_comments =
|
recent_comments =
|
||||||
Elasticsearch.search_records(
|
Comment
|
||||||
Comment,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -91,9 +95,9 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
},
|
},
|
||||||
sort: %{posted_at: :desc}
|
sort: %{posted_at: :desc}
|
||||||
},
|
},
|
||||||
%{page_size: 3},
|
%{page_size: 3}
|
||||||
Comment |> preload(user: [awards: :badge], image: :tags)
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Comment, user: [awards: :badge], image: :tags))
|
||||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.image))
|
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.image))
|
||||||
|
|
||||||
recent_comments =
|
recent_comments =
|
||||||
|
@ -102,8 +106,8 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
|> Enum.zip(recent_comments)
|
|> Enum.zip(recent_comments)
|
||||||
|
|
||||||
recent_posts =
|
recent_posts =
|
||||||
Elasticsearch.search_records(
|
Post
|
||||||
Post,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -117,9 +121,9 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
},
|
},
|
||||||
sort: %{created_at: :desc}
|
sort: %{created_at: :desc}
|
||||||
},
|
},
|
||||||
%{page_size: 6},
|
%{page_size: 6}
|
||||||
Post |> preload(user: [awards: :badge], topic: :forum)
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Post, user: [awards: :badge], topic: :forum))
|
||||||
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.topic))
|
|> Enum.filter(&Canada.Can.can?(current_user, :show, &1.topic))
|
||||||
|
|
||||||
about_me = TextileRenderer.render_one(%{body: user.description || ""}, conn)
|
about_me = TextileRenderer.render_one(%{body: user.description || ""}, conn)
|
||||||
|
@ -220,7 +224,7 @@ defmodule PhilomenaWeb.ProfileController do
|
||||||
pagination: %{page_number: 1, page_size: 4}
|
pagination: %{page_number: 1, page_size: 4}
|
||||||
)
|
)
|
||||||
|
|
||||||
images
|
Elasticsearch.search_records(images, preload(Image, :tags))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp set_admin_metadata(conn, _opts) do
|
defp set_admin_metadata(conn, _opts) do
|
||||||
|
|
|
@ -2,13 +2,17 @@ defmodule PhilomenaWeb.SearchController do
|
||||||
use PhilomenaWeb, :controller
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Elasticsearch
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
def index(conn, params) do
|
def index(conn, params) do
|
||||||
user = conn.assigns.current_user
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
case ImageLoader.search_string(conn, params["q"], include_hits: custom_ordering?(conn)) do
|
case ImageLoader.search_string(conn, params["q"]) do
|
||||||
{:ok, {images, tags}} ->
|
{:ok, {images, tags}} ->
|
||||||
|
images = search_function(custom_ordering?(conn)).(images, preload(Image, :tags))
|
||||||
interactions = Interactions.user_interactions(images, user)
|
interactions = Interactions.user_interactions(images, user)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -31,6 +35,9 @@ defmodule PhilomenaWeb.SearchController do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp search_function(true), do: &Elasticsearch.search_records_with_hits/2
|
||||||
|
defp search_function(_custom), do: &Elasticsearch.search_records/2
|
||||||
|
|
||||||
defp custom_ordering?(%{params: %{"sf" => sf}}) when sf != "id", do: true
|
defp custom_ordering?(%{params: %{"sf" => sf}}) when sf != "id", do: true
|
||||||
defp custom_ordering?(_conn), do: false
|
defp custom_ordering?(_conn), do: false
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,8 +12,8 @@ defmodule PhilomenaWeb.Tag.AutocompleteController do
|
||||||
[]
|
[]
|
||||||
|
|
||||||
term ->
|
term ->
|
||||||
Elasticsearch.search_records(
|
Tag
|
||||||
Tag,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -25,9 +25,9 @@ defmodule PhilomenaWeb.Tag.AutocompleteController do
|
||||||
},
|
},
|
||||||
sort: %{images: :desc}
|
sort: %{images: :desc}
|
||||||
},
|
},
|
||||||
%{page_size: 5},
|
%{page_size: 5}
|
||||||
Tag |> preload(:aliased_tag)
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Tag, :aliased_tag))
|
||||||
|> Enum.map(&(&1.aliased_tag || &1))
|
|> Enum.map(&(&1.aliased_tag || &1))
|
||||||
|> Enum.uniq_by(& &1.id)
|
|> Enum.uniq_by(& &1.id)
|
||||||
|> Enum.sort_by(&(-&1.images_count))
|
|> Enum.sort_by(&(-&1.images_count))
|
||||||
|
|
|
@ -4,8 +4,10 @@ defmodule PhilomenaWeb.TagController do
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
alias Philomena.Elasticsearch
|
alias Philomena.Elasticsearch
|
||||||
alias Philomena.{Tags, Tags.Tag}
|
alias Philomena.{Tags, Tags.Tag}
|
||||||
|
alias Philomena.Images.Image
|
||||||
alias PhilomenaWeb.TextileRenderer
|
alias PhilomenaWeb.TextileRenderer
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
plug PhilomenaWeb.RecodeParameterPlug, [name: "id"] when action in [:show]
|
plug PhilomenaWeb.RecodeParameterPlug, [name: "id"] when action in [:show]
|
||||||
plug PhilomenaWeb.CanaryMapPlug, update: :edit
|
plug PhilomenaWeb.CanaryMapPlug, update: :edit
|
||||||
|
@ -32,16 +34,16 @@ defmodule PhilomenaWeb.TagController do
|
||||||
|
|
||||||
with {:ok, query} <- Tags.Query.compile(query_string) do
|
with {:ok, query} <- Tags.Query.compile(query_string) do
|
||||||
tags =
|
tags =
|
||||||
Elasticsearch.search_records(
|
Tag
|
||||||
Tag,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: query,
|
query: query,
|
||||||
size: 250,
|
size: 250,
|
||||||
sort: [%{images: :desc}, %{name: :asc}]
|
sort: [%{images: :desc}, %{name: :asc}]
|
||||||
},
|
},
|
||||||
%{conn.assigns.pagination | page_size: 250},
|
%{conn.assigns.pagination | page_size: 250}
|
||||||
Tag
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(Tag)
|
||||||
|
|
||||||
render(conn, "index.html", title: "Tags", tags: tags)
|
render(conn, "index.html", title: "Tags", tags: tags)
|
||||||
else
|
else
|
||||||
|
@ -56,6 +58,8 @@ defmodule PhilomenaWeb.TagController do
|
||||||
|
|
||||||
{images, _tags} = ImageLoader.query(conn, %{term: %{"namespaced_tags.name" => tag.name}})
|
{images, _tags} = ImageLoader.query(conn, %{term: %{"namespaced_tags.name" => tag.name}})
|
||||||
|
|
||||||
|
images = Elasticsearch.search_records(images, preload(Image, :tags))
|
||||||
|
|
||||||
interactions = Interactions.user_interactions(images, user)
|
interactions = Interactions.user_interactions(images, user)
|
||||||
|
|
||||||
body = TextileRenderer.render_one(%{body: tag.description || ""}, conn)
|
body = TextileRenderer.render_one(%{body: tag.description || ""}, conn)
|
||||||
|
|
|
@ -20,7 +20,6 @@ defmodule PhilomenaWeb.ImageLoader do
|
||||||
|
|
||||||
def query(conn, body, options \\ []) do
|
def query(conn, body, options \\ []) do
|
||||||
pagination = Keyword.get(options, :pagination, conn.assigns.image_pagination)
|
pagination = Keyword.get(options, :pagination, conn.assigns.image_pagination)
|
||||||
queryable = Keyword.get(options, :queryable, Image |> preload(:tags))
|
|
||||||
sorts = Keyword.get(options, :sorts, &ImageSorter.parse_sort(conn.params, &1))
|
sorts = Keyword.get(options, :sorts, &ImageSorter.parse_sort(conn.params, &1))
|
||||||
|
|
||||||
tags =
|
tags =
|
||||||
|
@ -35,8 +34,8 @@ defmodule PhilomenaWeb.ImageLoader do
|
||||||
|
|
||||||
%{query: query, sorts: sort} = sorts.(body)
|
%{query: query, sorts: sort} = sorts.(body)
|
||||||
|
|
||||||
records =
|
definition =
|
||||||
search_function(options).(
|
Elasticsearch.search_definition(
|
||||||
Image,
|
Image,
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
|
@ -47,11 +46,10 @@ defmodule PhilomenaWeb.ImageLoader do
|
||||||
},
|
},
|
||||||
sort: sort
|
sort: sort
|
||||||
},
|
},
|
||||||
pagination,
|
pagination
|
||||||
queryable
|
|
||||||
)
|
)
|
||||||
|
|
||||||
{records, tags}
|
{definition, tags}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp create_filters(conn, user, filter) do
|
defp create_filters(conn, user, filter) do
|
||||||
|
@ -95,17 +93,6 @@ defmodule PhilomenaWeb.ImageLoader do
|
||||||
defp maybe_custom_hide(filters, _user, _param),
|
defp maybe_custom_hide(filters, _user, _param),
|
||||||
do: filters
|
do: filters
|
||||||
|
|
||||||
# Allow callers to choose if they want inner hit objects returned;
|
|
||||||
# primarily useful for allowing client navigation through images
|
|
||||||
|
|
||||||
@spec search_function(Keyword.t()) :: function()
|
|
||||||
defp search_function(options) do
|
|
||||||
case Keyword.get(options, :include_hits) do
|
|
||||||
true -> &Elasticsearch.search_records_with_hits/4
|
|
||||||
_false -> &Elasticsearch.search_records/4
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# TODO: the search parser should try to optimize queries
|
# TODO: the search parser should try to optimize queries
|
||||||
defp search_tag_name(%{term: %{"namespaced_tags.name" => tag_name}}), do: [tag_name]
|
defp search_tag_name(%{term: %{"namespaced_tags.name" => tag_name}}), do: [tag_name]
|
||||||
defp search_tag_name(_other_query), do: []
|
defp search_tag_name(_other_query), do: []
|
||||||
|
|
|
@ -51,7 +51,9 @@ defmodule PhilomenaWeb.ImageNavigator do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_search_after(module, body, options, queryable, true) do
|
defp maybe_search_after(module, body, options, queryable, true) do
|
||||||
Elasticsearch.search_records_with_hits(module, body, options, queryable)
|
module
|
||||||
|
|> Elasticsearch.search_definition(body, options)
|
||||||
|
|> Elasticsearch.search_records_with_hits(queryable)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_search_after(_module, _body, _options, _queryable, _false) do
|
defp maybe_search_after(_module, _body, _options, _queryable, _false) do
|
||||||
|
|
|
@ -132,8 +132,8 @@ defmodule PhilomenaWeb.TagView do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp implied_by_multitag(tag_names, ignore_tag_names) do
|
defp implied_by_multitag(tag_names, ignore_tag_names) do
|
||||||
Elasticsearch.search_records(
|
Tag
|
||||||
Tag,
|
|> Elasticsearch.search_definition(
|
||||||
%{
|
%{
|
||||||
query: %{
|
query: %{
|
||||||
bool: %{
|
bool: %{
|
||||||
|
@ -143,9 +143,9 @@ defmodule PhilomenaWeb.TagView do
|
||||||
},
|
},
|
||||||
sort: %{images: :desc}
|
sort: %{images: :desc}
|
||||||
},
|
},
|
||||||
%{page_size: 40},
|
%{page_size: 40}
|
||||||
Tag |> preload(:implied_tags)
|
|
||||||
)
|
)
|
||||||
|
|> Elasticsearch.search_records(preload(Tag, :implied_tags))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp manages_links?(conn),
|
defp manages_links?(conn),
|
||||||
|
|
Loading…
Reference in a new issue