search: make order:random truly random; add random:N metatag.
Make the `order:random` metatag truly randomize the search. Add a `random:N` metatag that returns up to N random posts, like what `order:random` did before. `order:random` now returns the entire search in random order. Before it just returned a pageful of pseudorandom posts. This will be more accurate for small searches, but slower for large searches. If `order:random` times out, try `random:N` instead. The `random:N` metatag returns up to N pseudorandom posts. This is faster than `order:random` for large searches, but for small searches, it may return less than N posts, and the randomness may be biased. Some posts may be more likely than others to appear. N must be between 0 and 200. Also, `/posts?tags=touhou&random=1` now redirects to `/posts?tags=touhou+random:N`. Before the `random=1` param acted like a free `order:random` tag; now it redirects to a `random:N` search, so it counts against your tag limit.
This commit is contained in:
@@ -38,7 +38,7 @@ class PostQueryBuilder
|
||||
ordpool note comment commentary id rating source status filetype
|
||||
disapproved parent child search embedded md5 width height mpixels ratio
|
||||
score upvotes downvotes favcount filesize date age order limit tagcount pixiv_id pixiv
|
||||
unaliased exif duration
|
||||
unaliased exif duration random
|
||||
] + COUNT_METATAGS + COUNT_METATAG_SYNONYMS + CATEGORY_COUNT_METATAGS
|
||||
|
||||
ORDER_METATAGS = %w[
|
||||
@@ -218,6 +218,8 @@ class PostQueryBuilder
|
||||
user_subquery_matches(PostVote.active.positive.visible(current_user), value, field: :user)
|
||||
when "downvoter", "downvote"
|
||||
user_subquery_matches(PostVote.active.negative.visible(current_user), value, field: :user)
|
||||
when "random"
|
||||
Post.all # handled in the `build` method
|
||||
when *CATEGORY_COUNT_METATAGS
|
||||
short_category = name.delete_suffix("tags")
|
||||
category = TagCategory.short_name_mapping[short_category]
|
||||
@@ -513,6 +515,11 @@ class PostQueryBuilder
|
||||
relation = search_order(relation, find_metatag(:order))
|
||||
end
|
||||
|
||||
if count = find_metatag(:random)
|
||||
count = Integer(count).clamp(0, PostSets::Post::MAX_PER_PAGE)
|
||||
relation = relation.random(count)
|
||||
end
|
||||
|
||||
relation
|
||||
end
|
||||
|
||||
@@ -688,6 +695,9 @@ class PostQueryBuilder
|
||||
when /(#{TagCategory.short_name_list.join("|")})tags_asc/
|
||||
relation = relation.order("posts.tag_count_#{TagCategory.short_name_mapping[$1]} ASC")
|
||||
|
||||
when "random"
|
||||
relation = relation.order("random()")
|
||||
|
||||
when "rank"
|
||||
relation = relation.where("posts.score > 0 and posts.created_at >= ?", 2.days.ago)
|
||||
relation = relation.order(Arel.sql("log(3, posts.score) + (extract(epoch from posts.created_at) - extract(epoch from timestamp '2005-05-24')) / 35000 DESC"))
|
||||
|
||||
Reference in New Issue
Block a user