(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 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]}) | |