diff --git a/src/metabase/models/card.clj b/src/metabase/models/card.clj index 8d82ac9ef0836c8d9d5a88f776e0f222e0a3a24d..a56455cfb55da5ccfc8a61b8236c1dddb234c3d0 100644 --- a/src/metabase/models/card.clj +++ b/src/metabase/models/card.clj @@ -1024,6 +1024,7 @@ :last-editor-id :r.user_id :pinned [:> [:coalesce :collection_position [:inline 0]] [:inline 0]] :verified [:= "verified" :mr.status] + :view-count true :created-at true :updated-at true} :search-terms [:name :description] diff --git a/src/metabase/models/dashboard.clj b/src/metabase/models/dashboard.clj index 368e34d6a320c431992d61166ab851f88950a7ed..0159f645a80ba6835c5bd594a884b758272ce124 100644 --- a/src/metabase/models/dashboard.clj +++ b/src/metabase/models/dashboard.clj @@ -674,6 +674,7 @@ :last-edited-at :r.timestamp :pinned [:> [:coalesce :collection_position [:inline 0]] [:inline 0]] :table-id false + :view-count true :created-at true :updated-at true} :search-terms [:name :description] diff --git a/src/metabase/models/table.clj b/src/metabase/models/table.clj index cd0209783f83222c6ccf33f696eaf56395069c88..c3cbab97889a0b45678f0c8c18215216e51ce957 100644 --- a/src/metabase/models/table.clj +++ b/src/metabase/models/table.clj @@ -309,6 +309,7 @@ ;; legacy search uses :active for this, but then has a rule to only ever show active tables ;; so we moved that to the where clause :archived false + :view-count true :created-at true :updated-at true} :search-terms [:name :description :display_name] diff --git a/src/metabase/search/config.clj b/src/metabase/search/config.clj index a9ca61f33a1e54af0d7496b563999d7bbea1b007..a60d4bcc14fd427fa1d470ed91285294cb71edf6 100644 --- a/src/metabase/search/config.clj +++ b/src/metabase/search/config.clj @@ -39,6 +39,10 @@ "Results in more dashboards than this are all considered to be equally popular." 10) +(def ^:const view-count-scaling + "The larger this value, the longer it will take for the score to approach 1.0. It will never quite reach it." + 50) + (def ^:const surrounding-match-context "Show this many words of context before/after matches in long search results" 2) @@ -77,15 +81,15 @@ (def weights "Strength of the various scorers. Copied from metabase.search.in-place.scoring, but allowing divergence." - {:pinned 2 ;; simple field - :bookmarked 2 ;; join with multi-table entity - :recency 1.5 ;; date formula - :dashboard 1 ;; simple field - :model 0.5 ;; simple field - :official-collection 2 ;; a field we can calculate - :verified 2 ;; a simple field - :text 10 ;; strength of text-scores-weight previously - }) + {:pinned 2 + :bookmarked 2 + :recency 1.5 + :dashboard 1 + :model 0.5 + :official-collection 2 + :verified 2 + :view-count 2 + :text 10}) (defn model->alias "Given a model string returns the model alias" diff --git a/src/metabase/search/postgres/core.clj b/src/metabase/search/postgres/core.clj index 6d143c81698c5c5567eefd48e158b3e626b1a654..a17556eb234ba19140601649f598a9b1ea91cd75 100644 --- a/src/metabase/search/postgres/core.clj +++ b/src/metabase/search/postgres/core.clj @@ -72,6 +72,8 @@ (OffsetDateTime/parse s))) (defn- rehydrate [index-row] + ;; Useful for debugging scoring + #_ (dissoc index-row :legacy_input :created_at :updated_at :last_edited_at) (-> (merge (json/parse-string (:legacy_input index-row) keyword) (select-keys index-row [:total_score :pinned])) diff --git a/src/metabase/search/postgres/index.clj b/src/metabase/search/postgres/index.clj index bfe35def584465439fe773e4942b5b715bcaa855..2291330f64182abc78b09913a2dd428f00b44812 100644 --- a/src/metabase/search/postgres/index.clj +++ b/src/metabase/search/postgres/index.clj @@ -56,6 +56,7 @@ [:model_rank :int :not-null] [:pinned :boolean] [:verified :boolean] + [:view_count :int] ;; permission related entities [:collection_id :int] [:database_id :int] diff --git a/src/metabase/search/postgres/scoring.clj b/src/metabase/search/postgres/scoring.clj index 16d7e09af97e8190657604ab2085189088067ff9..cf390385c4796349fa33b29882a0f9d781760f9a 100644 --- a/src/metabase/search/postgres/scoring.clj +++ b/src/metabase/search/postgres/scoring.clj @@ -15,6 +15,14 @@ [column ceiling] [:least [:/ [:coalesce column [:inline 0]] [:inline (double ceiling)]] [:inline 1]]) +(defn- atan-size + "Prefer items whose value is larger, with diminishing gains." + [column scaling] + ;; 2/PI * tan^-1 (x/N) + [:* + [:/ [:inline 2] [:pi]] + [:atan [:/ [:cast [:coalesce column [:inline 0.0]] :float] [:inline scaling]]]]) + (defn- inverse-duration "Score at item based on the duration between two dates, where less is better." [from-column to-column ceiling-in-days] @@ -67,6 +75,7 @@ (def ^:private scorers {:text [:ts_rank :search_vector :query [:inline ts-rank-normalization]] + :view-count (atan-size :view_count search.config/view-count-scaling) :pinned (truthy :pinned) :bookmarked bookmark-score-expr :recency (inverse-duration :model_updated_at [:now] search.config/stale-time-in-days) diff --git a/src/metabase/search/spec.clj b/src/metabase/search/spec.clj index 74014434e70abc79b0b14765c3c4e8fabab5d09c..969646bb9156e10158b2e6119a16aedd0fe6135b 100644 --- a/src/metabase/search/spec.clj +++ b/src/metabase/search/spec.clj @@ -41,6 +41,7 @@ :last-editor-id :pinned :verified + :view-count :updated-at]) (def ^:private default-attrs diff --git a/test/metabase/search/spec_test.clj b/test/metabase/search/spec_test.clj index 399521754e01343400a24d4aea43664179202c3e..047852a1893ea2c0596cea48d3a1b0972604fdab 100644 --- a/test/metabase/search/spec_test.clj +++ b/test/metabase/search/spec_test.clj @@ -70,6 +70,7 @@ :name :query_type :type + :view_count :created_at :updated_at}, :where [:= :updated.id :this.id]}}, @@ -99,7 +100,7 @@ {:search-model "table", :fields #{:active :description :schema :name :id :db_id :initial_sync_status :display_name - :visibility_type :created_at :updated_at} + :visibility_type :view_count :created_at :updated_at} :where [:= :updated.id :this.id]}}, :Database #{{:search-model "table", :fields #{:name}, :where [:= :updated.id :this.db_id]}} :Segment #{{:search-model "segment"