[#3213] Speedup of HashtagsTableMigrator (query optimization). State handling fix.
authorIvan Tashkinov <ivantashkinov@gmail.com>
Sun, 24 Jan 2021 20:27:02 +0000 (23:27 +0300)
committerIvan Tashkinov <ivantashkinov@gmail.com>
Sun, 24 Jan 2021 20:27:02 +0000 (23:27 +0300)
lib/pleroma/migrators/hashtags_table_migrator.ex
lib/pleroma/migrators/hashtags_table_migrator/state.ex

index 8ad2c8c73a8930c2cc7e50b43b58c19a613032af..6a1c9592c46f6676ba24c431dc42343cfe89f8e4 100644 (file)
@@ -72,6 +72,8 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
 
   @impl true
   def handle_info(:migrate_hashtags, state) do
+    State.clear()
+
     data_migration = data_migration()
 
     persistent_data = Map.take(data_migration.data, ["max_processed_id"])
@@ -152,8 +154,6 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
     # Note: most objects have Mention-type AS2 tags and no hashtags (but we can't filter them out)
     from(
       object in Object,
-      left_join: hashtag in assoc(object, :hashtags),
-      where: is_nil(hashtag.id),
       where:
         fragment("(?)->'tag' IS NOT NULL AND (?)->'tag' != '[]'::jsonb", object.data, object.data),
       select: %{
@@ -161,12 +161,24 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator do
         tag: fragment("(?)->'tag'", object.data)
       }
     )
+    |> join(:left, [o], hashtags_objects in fragment("SELECT object_id FROM hashtags_objects"),
+      on: hashtags_objects.object_id == o.id
+    )
+    |> where([_o, hashtags_objects], is_nil(hashtags_objects.object_id))
   end
 
   defp transfer_object_hashtags(object) do
-    embedded_tags = (Map.has_key?(object, :tag) && object.tag) || object.data["tag"]
+    embedded_tags = if Map.has_key?(object, :tag), do: object.tag, else: object.data["tag"]
     hashtags = Object.object_data_hashtags(%{"tag" => embedded_tags})
 
+    if Enum.any?(hashtags) do
+      transfer_object_hashtags(object, hashtags)
+    else
+      {:ok, object.id}
+    end
+  end
+
+  defp transfer_object_hashtags(object, hashtags) do
     Repo.transaction(fn ->
       with {:ok, hashtag_records} <- Hashtag.get_or_create_by_names(hashtags) do
         for hashtag_record <- hashtag_records do
index 43f7270e25fa7d1f443f1b2448b3bb5e22b5a1fc..901563426876dfb52923a1fe6eeab7e5760dc684 100644 (file)
@@ -12,6 +12,10 @@ defmodule Pleroma.Migrators.HashtagsTableMigrator.State do
     Agent.start_link(fn -> @init_state end, name: @reg_name)
   end
 
+  def clear do
+    Agent.update(@reg_name, fn _state -> @init_state end)
+  end
+
   def get do
     Agent.get(@reg_name, & &1)
   end