| |
|
| (ns metabase.search.appdb.specialization.h2
(:require
[clojure.math :as math]
[clojure.string :as str]
[honey.sql.helpers :as sql.helpers]
[metabase.search.appdb.specialization.api :as specialization]
[metabase.util :as u]
[toucan2.core :as t2])) |
|
| (defmethod specialization/table-schema :h2 [base-schema]
(into [[:id :bigint :auto-increment :primary-key]
[:search_terms :text]
[:native_search_terms :text]]
base-schema)) |
|
| (defmethod specialization/post-create-statements :h2 [prefix table-name]
(mapv
(fn [template] (format template prefix table-name))
["CREATE UNIQUE INDEX %s_identity_idx ON %s (model, model_id)"])) |
|
| (defmethod specialization/batch-upsert! :h2 [table entries]
;; it's in memory, let's just do it quick and dirty (HoneySQL can't speak MERGE WITH)
;; TODO just generate raw SQL
(when (seq entries)
(doseq [{:keys [model model_id]} entries]
(t2/delete! table :model model :model_id (str model_id)))
(t2/insert! table entries))) |
|
| (defn- wildcard-tokens [search-term]
(->> (str/split search-term #"\s+")
(map #(u/lower-case-en (str/trim %)))
(remove str/blank?)
(map (fn [s] (str "%" s "%"))))) |
|
| (defmethod specialization/base-query :h2
[active-table search-term search-ctx select-items]
(let [search-column (if (:search-native-query search-ctx)
:search_index.native_search_terms
:search_index.search_terms)]
(cond-> {:select select-items
:from [[active-table :search_index]]}
(not (str/blank? search-term))
(sql.helpers/where (into [:and] (for [pattern (wildcard-tokens search-term)]
[:like [:lower search-column] pattern])))))) |
|
| (defmethod specialization/extra-entry-fields :h2 [entity]
{:search_terms (:searchable_text entity)
:native_search_terms (str/join " " (keep entity [:searchable_text :native_query]))}) |
|
| (defmethod specialization/text-score :h2 []
[:inline 1]) |
|
| (defmethod specialization/view-count-percentile-query :h2
[index-table p-value]
;; Since H2 doesn't support calculating percentiles, we just scale the max >_<
;; We take the power of the p-value to simulate a one-sided, long-tailed distribution
{:select [:search_index.model [[:* [:inline (math/pow p-value 10)] [:max :view_count]] :vcp]]
:from [[index-table :search_index]]
:group-by [:search_index.model]}) |
| | |