Allow to order search results by the topic creation date

based on: https://meta.discourse.org/t/allow-to-order-search-results-by-the-topic-creation-date/38544
This commit is contained in:
Yana Agun Siswanto 2017-03-30 00:33:23 +07:00
parent 3914f746b8
commit cd2d2f16e5
4 changed files with 36 additions and 1 deletions

View File

@ -11,6 +11,8 @@ const SortOrders = [
{name: I18n.t('search.latest_post'), id: 1, term: 'order:latest'}, {name: I18n.t('search.latest_post'), id: 1, term: 'order:latest'},
{name: I18n.t('search.most_liked'), id: 2, term: 'order:likes'}, {name: I18n.t('search.most_liked'), id: 2, term: 'order:likes'},
{name: I18n.t('search.most_viewed'), id: 3, term: 'order:views'}, {name: I18n.t('search.most_viewed'), id: 3, term: 'order:views'},
{name: I18n.t('search.latest_topic'), id: 4, term: 'order:latest_topic'},
]; ];
export default Ember.Controller.extend({ export default Ember.Controller.extend({
@ -90,7 +92,9 @@ export default Ember.Controller.extend({
this._searchOnSortChange = false; this._searchOnSortChange = false;
if (term) { if (term) {
SortOrders.forEach(order => { SortOrders.forEach(order => {
if (term.indexOf(order.term) > -1){ let term_start = term.indexOf(order.term)
let char_after_term = term[term_start + (order.term || '').length]
if (term_start > -1 && (!char_after_term || char_after_term.match(/\s/))){
this.set('sortOrder', order.id); this.set('sortOrder', order.id);
term = term.replace(order.term, ""); term = term.replace(order.term, "");
term = term.trim(); term = term.trim();

View File

@ -1276,6 +1276,7 @@ en:
sort_by: "Sort by" sort_by: "Sort by"
relevance: "Relevance" relevance: "Relevance"
latest_post: "Latest Post" latest_post: "Latest Post"
latest_topic: "Latest Topic"
most_viewed: "Most Viewed" most_viewed: "Most Viewed"
most_liked: "Most Liked" most_liked: "Most Liked"
select_all: "Select All" select_all: "Select All"

View File

@ -477,6 +477,9 @@ class Search
if word == 'order:latest' if word == 'order:latest'
@order = :latest @order = :latest
nil nil
elsif word == 'order:latest_topic'
@order = :latest_topic
nil
elsif word =~ /topic:(\d+)/ elsif word =~ /topic:(\d+)/
topic_id = $1.to_i topic_id = $1.to_i
if topic_id > 1 if topic_id > 1
@ -680,6 +683,12 @@ class Search
else else
posts = posts.order("posts.created_at DESC") posts = posts.order("posts.created_at DESC")
end end
elsif @order == :latest_topic
if opts[:aggregate_search]
posts = posts.order("MAX(topics.created_at) DESC")
else
posts = posts.order("topics.created_at DESC")
end
elsif @order == :views elsif @order == :views
if opts[:aggregate_search] if opts[:aggregate_search]
posts = posts.order("MAX(topics.views) DESC") posts = posts.order("MAX(topics.views) DESC")

View File

@ -613,7 +613,28 @@ describe Search do
expect(Search.execute('sam').posts.map(&:id)).to eq([post1.id, post2.id]) expect(Search.execute('sam').posts.map(&:id)).to eq([post1.id, post2.id])
expect(Search.execute('sam order:latest').posts.map(&:id)).to eq([post2.id, post1.id]) expect(Search.execute('sam order:latest').posts.map(&:id)).to eq([post2.id, post1.id])
end
it 'can order by topic creation' do
today = Date.today
yesterday = 1.day.ago
two_days_ago = 2.days.ago
old_topic = Fabricate(:topic,
title: 'First Topic, testing the created_at sort',
created_at: two_days_ago)
latest_topic = Fabricate(:topic,
title: 'Second Topic, testing the created_at sort',
created_at: yesterday)
old_relevant_topic_post = Fabricate(:post, topic: old_topic, created_at: yesterday, raw: 'Relevant Topic')
latest_irelevant_topic_post = Fabricate(:post, topic: latest_topic, created_at: today, raw: 'Not Relevant')
# Expecting the default results
expect(Search.execute('Topic').posts.map(&:id)).to eq([old_relevant_topic_post.id, latest_irelevant_topic_post.id])
# Expecting the ordered by topic creation results
expect(Search.execute('Topic order:latest_topic').posts.map(&:id)).to eq([latest_irelevant_topic_post.id, old_relevant_topic_post.id])
end end
it 'can tokenize dots' do it 'can tokenize dots' do