Skip to content

Commit

Permalink
Improve textSearch_profiles result (#3134)
Browse files Browse the repository at this point in the history
* Version 1: implementing new version of profiles endpoint and fixing recentPeople endpoint

* Code climate

* Code climate

* Code climate [2]

* Code climate [3]

* Code climate [4]

* Refactoring getRecentProfiles method

* fixing order_by X sort_by

* Trying to fix travis error

* trying to fix travis again

* using find_users

* Fix User.search query

* Fixing conflict

* Giving better names for the methods

* Hacking travis
  • Loading branch information
milaaraujo authored and jywarren committed Aug 14, 2018
1 parent ed75ab7 commit 17827d1
Show file tree
Hide file tree
Showing 18 changed files with 539 additions and 345 deletions.
9 changes: 6 additions & 3 deletions app/api/srch/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ class Search < Grape::API
Search.execute(:all, params)
end

# Request URL should be /api/srch/profiles?srchString=QRY[&seq=KEYCOUNT&showCount=NUM_ROWS&pageNum=PAGE_NUM]
# Request URL should be /api/srch/profiles?srchString=QRY[&sort_by=recent&order_direction=desc&seq=KEYCOUNT&showCount=NUM_ROWS&pageNum=PAGE_NUM]
# Basic implementation from classic plots2 SearchController
desc 'Perform a search of profiles', hidden: false,
is_array: false,
nickname: 'srchGetProfiles'

params do
use :common
use :common, :sorting, :ordering
end
get :profiles do
Search.execute(:profiles, params)
Expand Down Expand Up @@ -105,12 +105,15 @@ def self.execute(endpoint, params)
sresult = DocList.new
search_query = params[:srchString]
tag_query = params[:tagName]
order_query = params[:order_direction]
sort_query = params[:sort_by]
search_type = endpoint
search_criteria = SearchCriteria.new(search_query, tag_query)
search_criteria = SearchCriteria.new(search_query, tag: tag_query, sort_by: sort_query, order_direction: order_query)

if search_criteria.valid?
sresult = ExecuteSearch.new.by(search_type, search_criteria)
end

sparms = SearchRequest.fromRequest(params)
sresult.srchParams = sparms
sresult
Expand Down
8 changes: 8 additions & 0 deletions app/api/srch/shared_params.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ module SharedParams
optional :tagName, type: String, documentation: { example: 'awesome' }
end

params :ordering do
optional :order_direction, type: String, documentation: { example: 'desc' }
end

params :sorting do
optional :sort_by, type: String, documentation: { example: 'recent' }
end

params :commontypeahead do
requires :srchString, type: String, documentation: { example: 'Spec' }
optional :seq, type: Integer, documentation: { example: 995 }
Expand Down
3 changes: 2 additions & 1 deletion app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class User < ActiveRecord::Base
has_many :following_users, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
has_many :likes
has_many :revisions, through: :node

validates_with UniqueUsernameValidator, on: :create
validates_format_of :username, with: /\A[A-Za-z\d_\-]+\z/
Expand All @@ -42,7 +43,7 @@ class User < ActiveRecord::Base
after_destroy :destroy_drupal_user

def self.search(query)
User.where('MATCH(username, bio) AGAINST(?)', query)
User.where('MATCH(bio, username) AGAINST(? IN BOOLEAN MODE)', query + '*')
end

def new_contributor
Expand Down
4 changes: 2 additions & 2 deletions app/services/execute_search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ def execute(type, search_criteria)
sresult = DocList.new
case type
when :all
sresult = sservice.textSearch_all(search_criteria.query)
sresult = sservice.textSearch_all(search_criteria)
when :profiles
sresult = sservice.textSearch_profiles(search_criteria.query)
sresult = sservice.profiles(search_criteria)
when :notes
sresult = sservice.textSearch_notes(search_criteria.query)
when :questions
Expand Down
22 changes: 20 additions & 2 deletions app/services/search_criteria.rb
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
class SearchCriteria
attr_reader :query, :tag
attr_reader :query, :tag, :sort_by

def initialize(query, tag = nil)
def initialize(query, tag: nil, sort_by: nil, order_direction: "DESC")
@query = query
@tag = tag
@sort_by = sort_by
@order_direction = order_direction
end

def valid?
!query.nil? && query != 0
end

def order_direction
sanitize_direction(@order_direction)
end

private

def sanitize_direction(direction)
if direction.present?
direction = direction.upcase
options = %w(DESC ASC)
options.include?(direction) ? direction : "DESC"
else
"DESC"
end
end
end
44 changes: 30 additions & 14 deletions app/services/search_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,60 @@ def initialize; end

# Run a search in any of the associated systems for references that contain the search string
# and package up as a DocResult
def textSearch_all(srchString)
def textSearch_all(search_criteria)
sresult = DocList.new

# notes
noteList = textSearch_notes(srchString)
noteList = textSearch_notes(search_criteria.query)
sresult.addAll(noteList.items)

# Node search
Node.limit(5)
.order('nid DESC')
.where('(type = "page" OR type = "place" OR type = "tool") AND node.status = 1 AND title LIKE ?', '%' + srchString + '%')
.where('(type = "page" OR type = "place" OR type = "tool") AND node.status = 1 AND title LIKE ?', '%' + search_criteria.query + '%')
.select('title,type,nid,path').each do |match|
doc = DocResult.fromSearch(match.nid, match.icon, match.path, match.title, '', 0)
sresult.addDoc(doc)
end
# User profiles
userList = textSearch_profiles(srchString)
userList = profiles(search_criteria)
sresult.addAll(userList.items)

# Tags
tagList = textSearch_tags(srchString)
tagList = textSearch_tags(search_criteria.query)
sresult.addAll(tagList.items)
# maps
mapList = textSearch_maps(srchString)
mapList = textSearch_maps(search_criteria.query)
sresult.addAll(mapList.items)
# questions
qList = textSearch_questions(srchString)
qList = textSearch_questions(search_criteria.query)
sresult.addAll(qList.items)

sresult
end

# Search profiles for matching text and package up as a DocResult
def textSearch_profiles(srchString)
sresult = DocList.new
# Search profiles for matching text with optional order_by=recent param and
# sorted direction DESC by default
# then the list is packaged up as a DocResult

users = SrchScope.find_users(srchString, limit = 10) # don't return hundreds!!
# User profiles
# If no sort_by value present, then it returns a list of profiles ordered by id DESC
# a recent activity may be a node creation or a node revision
def profiles(search_criteria)
user_scope = SrchScope.find_users(search_criteria.query, limit = 10)

user_scope =
if search_criteria.sort_by == "recent"
user_scope.joins(:revisions)
.order("node_revisions.timestamp #{search_criteria.order_direction}")
.distinct

else
user_scope.order(id: :desc)
end

users = user_scope.limit(10)

sresult = DocList.new
users.each do |match|
doc = DocResult.fromSearch(0, 'user', '/profile/' + match.name, match.name, '', 0)
sresult.addDoc(doc)
Expand Down Expand Up @@ -167,10 +183,10 @@ def tagNearbyNodes(srchString, tagName)

# GET X number of latest people/contributors and package up as a DocResult
# X = srchString
def recentPeople(srchString, tagName = nil)
def recentPeople(_srchString, tagName = nil)
sresult = DocList.new

nodes = Node.all.order("changed DESC").limit(srchString).distinct
nodes = Node.all.order("changed DESC").limit(100).distinct
users = []
nodes.each do |node|
if node.author.status != 0
Expand Down
10 changes: 4 additions & 6 deletions app/services/srch_scope.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
# This class provides common methods that Typehead and Search services use
class SrchScope
def self.find_users(input, limit)
def self.find_users(query, limit)
if ActiveRecord::Base.connection.adapter_name == 'Mysql2'
User.search(input)
.order('id DESC')
.where(status: 1)
User.search(query)
.where('rusers.status = ?', 1)
.limit(limit)
else
User.order('id DESC')
.where('username LIKE ? AND status = 1', '%' + input + '%')
User.where('username LIKE ? AND rusers.status = 1', '%' + input + '%')
.limit(limit)
end
end
Expand Down
2 changes: 1 addition & 1 deletion db/migrate/20120101000000_drupal_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ def up
unless index_exists? "url_alias", [:dst, :language, :pid], name: "dst_language_pid"
add_index "url_alias", ["dst", "language", "pid"], :name => "dst_language_pid"
end

unless index_exists? "url_alias", [:src, :language, :pid], name: "src_language_pid"
add_index "url_alias", ["src", "language", "pid"], :name => "src_language_pid"
end
Expand Down
13 changes: 13 additions & 0 deletions db/migrate/20180804042601_add_full_text_index_on_username.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class AddFullTextIndexOnUsername < ActiveRecord::Migration[5.2]
def up
if ActiveRecord::Base.connection.adapter_name == 'Mysql2'
add_index :rusers, :username, type: :fulltext, name: 'rusers_username_fulltext_idx'
end
end

def down
if ActiveRecord::Base.connection.adapter_name == 'Mysql2'
remove_index :rusers, name: 'rusers_username_fulltext_idx'
end
end
end
Loading

0 comments on commit 17827d1

Please sign in to comment.