autocomplete: make number of results configurable (partly).

Add `Danbooru.Autocomplete.MAX_RESULTS` param that controls the number
of results returned by autocomplete.

This does not work with tag autocomplete for Builders. Builder
autocomplete still needs to be refactored and unified with Member
autocomplete.

Also fix a bug in the /saved_searches/labels endpoint where the limit
param wasn't respected.
This commit is contained in:
evazion
2019-11-13 01:39:03 -06:00
parent 89c5ac73af
commit 378559ff47
4 changed files with 16 additions and 14 deletions

View File

@@ -7,7 +7,7 @@ class SavedSearchesController < ApplicationController
end
def labels
@labels = SavedSearch.search_labels(CurrentUser.id, params[:search])
@labels = SavedSearch.search_labels(CurrentUser.id, params[:search]).take(params[:limit].to_i || 10)
respond_with(@labels)
end

View File

@@ -18,7 +18,7 @@ class TagsController < ApplicationController
# limit rollout
@tags = TagAutocomplete.search(params[:search][:name_matches])
else
@tags = Tag.names_matches_with_aliases(params[:search][:name_matches])
@tags = Tag.names_matches_with_aliases(params[:search][:name_matches], limit: params[:limit])
end
# XXX

View File

@@ -11,6 +11,7 @@ Autocomplete.ORDER_METATAGS = <%= Tag::ORDER_METATAGS.to_json.html_safe %>;
Autocomplete.TAG_PREFIXES = "-|~|" + Object.keys(Autocomplete.TAG_CATEGORIES).map(category => category + ":").join("|");
Autocomplete.METATAGS_REGEX = Autocomplete.METATAGS.concat(Object.keys(Autocomplete.TAG_CATEGORIES)).join("|");
Autocomplete.TERM_REGEX = new RegExp(`([-~]*)(?:(${Autocomplete.METATAGS_REGEX}):)?(\\S*)$`, "i");
Autocomplete.MAX_RESULTS = 10;
Autocomplete.initialize_all = function() {
if (CurrentUser.data("enable-auto-complete")) {
@@ -288,7 +289,7 @@ Autocomplete.static_metatag_source = function(term, metatag) {
var sub_metatags = this.static_metatags[metatag];
var matches = sub_metatags.filter(sub_metatag => sub_metatag.startsWith(term.toLowerCase()));
matches = matches.map(sub_metatag => `${metatag}:${sub_metatag}`).sort().slice(0, 10);
matches = matches.map(sub_metatag => `${metatag}:${sub_metatag}`).sort().slice(0, Autocomplete.MAX_RESULTS);
return matches;
}
@@ -300,6 +301,7 @@ Autocomplete.tag_source = async function(term) {
let tags = await $.getJSON("/tags/autocomplete", {
"search[name_matches]": term,
"limit": Autocomplete.MAX_RESULTS,
"expiry": 7
});
@@ -322,7 +324,7 @@ Autocomplete.artist_source = async function(term) {
"search[name_like]": term.trim().replace(/\s+/g, "_") + "*",
"search[is_active]": true,
"search[order]": "post_count",
"limit": 10,
"limit": Autocomplete.MAX_RESULTS,
"expiry": 7
});
@@ -341,7 +343,7 @@ Autocomplete.wiki_source = async function(term) {
"search[title]": term + "*",
"search[hide_deleted]": "Yes",
"search[order]": "post_count",
"limit": 10,
"limit": Autocomplete.MAX_RESULTS,
"expiry": 7
});
@@ -360,7 +362,7 @@ Autocomplete.user_source = async function(term, prefix = "") {
"search[order]": "post_upload_count",
"search[current_user_first]": "true",
"search[name_matches]": term + "*",
"limit": 10
"limit": Autocomplete.MAX_RESULTS
});
return users.map(function(user) {
@@ -378,7 +380,7 @@ Autocomplete.pool_source = async function(term, prefix = "") {
"search[name_matches]": term,
"search[is_deleted]": false,
"search[order]": "post_count",
"limit": 10
"limit": Autocomplete.MAX_RESULTS
});
return pools.map(function(pool) {
@@ -395,7 +397,7 @@ Autocomplete.pool_source = async function(term, prefix = "") {
Autocomplete.favorite_group_source = async function(term, prefix = "") {
let favgroups = await $.getJSON("/favorite_groups", {
"search[name_matches]": term,
"limit": 10
"limit": Autocomplete.MAX_RESULTS
});
return favgroups.map(function(favgroup) {
@@ -410,7 +412,7 @@ Autocomplete.favorite_group_source = async function(term, prefix = "") {
Autocomplete.saved_search_source = async function(term, prefix = "") {
let labels = await $.getJSON("/saved_searches/labels", {
"search[label]": term + "*",
"limit": 10
"limit": Autocomplete.MAX_RESULTS
});
return labels.map(function(label) {

View File

@@ -895,12 +895,12 @@ class Tag < ApplicationRecord
q
end
def names_matches_with_aliases(name)
def names_matches_with_aliases(name, limit: 10)
name = normalize_name(name)
wildcard_name = name + '*'
query1 = Tag.select("tags.name, tags.post_count, tags.category, null AS antecedent_name")
.search(:name_matches => wildcard_name, :order => "count").limit(10)
.search(:name_matches => wildcard_name, :order => "count").limit(limit)
query2 = TagAlias.select("tags.name, tags.post_count, tags.category, tag_aliases.antecedent_name")
.joins("INNER JOIN tags ON tags.name = tag_aliases.consequent_name")
@@ -909,13 +909,13 @@ class Tag < ApplicationRecord
.where("tags.name NOT LIKE ? ESCAPE E'\\\\'", wildcard_name.to_escaped_for_sql_like)
.where("tag_aliases.post_count > 0")
.order("tag_aliases.post_count desc")
.limit(20) # Get 20 records even though only 10 will be displayed in case some duplicates get filtered out.
.limit(limit * 2) # Get extra records in case some duplicates get filtered out.
sql_query = "((#{query1.to_sql}) UNION ALL (#{query2.to_sql})) AS unioned_query"
tags = Tag.select("DISTINCT ON (name, post_count) *").from(sql_query).order("post_count desc").limit(10)
tags = Tag.select("DISTINCT ON (name, post_count) *").from(sql_query).order("post_count desc").limit(limit)
if tags.empty?
tags = Tag.select("tags.name, tags.post_count, tags.category, null AS antecedent_name").fuzzy_name_matches(name).order_similarity(name).nonempty.limit(10)
tags = Tag.select("tags.name, tags.post_count, tags.category, null AS antecedent_name").fuzzy_name_matches(name).order_similarity(name).nonempty.limit(limit)
end
tags