From cf1626494047f27d8fe094a7b954e04fef0f182b Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 13 Apr 2018 09:22:55 +0200 Subject: [PATCH] Implemented issue #1951 - Allow pagination in search result with more then 100 results. --- app/controllers/organizations_controller.rb | 23 +++++++--------- app/controllers/tickets_controller.rb | 23 +++++++--------- app/controllers/users_controller.rb | 29 ++++++++++++++++----- app/models/chat/session/search.rb | 6 +++-- app/models/organization/search.rb | 6 +++-- app/models/ticket/search.rb | 8 +++++- app/models/user/search.rb | 9 ++++--- lib/search_index_backend.rb | 10 +++---- 8 files changed, 66 insertions(+), 48 deletions(-) diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 823109586..c9b1cc72f 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -229,14 +229,14 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co raise Exceptions::NotAuthorized end - # set limit for pagination if needed - if params[:page] && params[:per_page] - params[:limit] = params[:page].to_i * params[:per_page].to_i - end - - if params[:limit] && params[:limit].to_i > 500 - params[:limit] = 500 + per_page = params[:per_page] || params[:limit] || 100 + per_page = per_page.to_i + if per_page > 500 + per_page = 500 end + page = params[:page] || 1 + page = page.to_i + offset = (page - 1) * per_page query = params[:query] if query.respond_to?(:permit!) @@ -244,7 +244,8 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co end query_params = { query: query, - limit: params[:limit], + limit: per_page, + offset: offset, current_user: current_user, } if params[:role_ids].present? @@ -254,12 +255,6 @@ curl http://localhost/api/v1/organization/{id} -v -u #{login}:#{password} -H "Co # do query organization_all = Organization.search(query_params) - # do pagination if needed - if params[:page] && params[:per_page] - offset = (params[:page].to_i - 1) * params[:per_page].to_i - organization_all = organization_all[offset, params[:per_page].to_i] || [] - end - if response_expand? list = [] organization_all.each do |organization| diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index cab614ae5..43403b2de 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -425,14 +425,14 @@ class TicketsController < ApplicationController params.require(:condition).permit! end - # set limit for pagination if needed - if params[:page] && params[:per_page] - params[:limit] = params[:page].to_i * params[:per_page].to_i - end - - if params[:limit] && params[:limit].to_i > 100 - params[:limit] = 100 + per_page = params[:per_page] || params[:limit] || 50 + per_page = per_page.to_i + if per_page > 200 + per_page = 200 end + page = params[:page] || 1 + page = page.to_i + offset = (page - 1) * per_page query = params[:query] if query.respond_to?(:permit!) @@ -443,16 +443,11 @@ class TicketsController < ApplicationController tickets = Ticket.search( query: query, condition: params[:condition].to_h, - limit: params[:limit], + limit: per_page, + offset: offset, current_user: current_user, ) - # do pagination if needed - if params[:page] && params[:per_page] - offset = (params[:page].to_i - 1) * params[:per_page].to_i - tickets = tickets[offset, params[:per_page].to_i] || [] - end - if response_expand? list = [] tickets.each do |ticket| diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index fa8f9432e..9cb3a9020 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -373,14 +373,28 @@ class UsersController < ApplicationController return end - # set limit for pagination if needed - if params[:page] && params[:per_page] - params[:limit] = params[:page].to_i * params[:per_page].to_i + per_page = params[:per_page] || params[:limit] || 100 + per_page = per_page.to_i + if per_page > 500 + per_page = 500 + end + page = params[:page] || 1 + page = page.to_i + offset = (page - 1) * per_page + + query = params[:query] + if query.respond_to?(:permit!) + query = query.permit!.to_h end - if params[:limit] && params[:limit].to_i > 500 - params[:limit] = 500 - end + # build result list + tickets = Ticket.search( + query: query, + condition: params[:condition].to_h, + limit: per_page, + offset: offset, + current_user: current_user, + ) query = params[:query] || params[:term] if query.respond_to?(:permit!) @@ -389,7 +403,8 @@ class UsersController < ApplicationController query_params = { query: query, - limit: params[:limit], + limit: per_page, + offset: offset, current_user: current_user, } %i[role_ids permissions].each do |key| diff --git a/app/models/chat/session/search.rb b/app/models/chat/session/search.rb index 87d12f1c9..240793a10 100644 --- a/app/models/chat/session/search.rb +++ b/app/models/chat/session/search.rb @@ -38,6 +38,7 @@ search organizations current_user: User.find(123), query: 'search something', limit: 15, + offset: 100, ) returns @@ -51,6 +52,7 @@ returns # get params query = params[:query] limit = params[:limit] || 10 + offset = params[:offset] || 0 current_user = params[:current_user] # enable search only for agents and admins @@ -58,7 +60,7 @@ returns # try search index backend if SearchIndexBackend.enabled? - items = SearchIndexBackend.search(query, limit, 'Chat::Session') + items = SearchIndexBackend.search(query, limit, 'Chat::Session', {}, offset) chat_sessions = [] items.each do |item| chat_session = Chat::Session.lookup(id: item[:id]) @@ -73,7 +75,7 @@ returns query.delete! '*' chat_sessions = Chat::Session.where( 'name LIKE ?', "%#{query}%" - ).order('name').limit(limit).to_a + ).order('name').offset(offset).limit(limit).to_a chat_sessions end end diff --git a/app/models/organization/search.rb b/app/models/organization/search.rb index a87c1969c..dc4f61e71 100644 --- a/app/models/organization/search.rb +++ b/app/models/organization/search.rb @@ -38,6 +38,7 @@ search organizations current_user: User.find(123), query: 'search something', limit: 15, + offset: 100, ) returns @@ -51,6 +52,7 @@ returns # get params query = params[:query] limit = params[:limit] || 10 + offset = params[:offset] || 0 current_user = params[:current_user] # enable search only for agents and admins @@ -58,7 +60,7 @@ returns # try search index backend if SearchIndexBackend.enabled? - items = SearchIndexBackend.search(query, limit, 'Organization') + items = SearchIndexBackend.search(query, limit, 'Organization', {}, offset) organizations = [] items.each do |item| organization = Organization.lookup(id: item[:id]) @@ -73,7 +75,7 @@ returns query.delete! '*' organizations = Organization.where( 'name LIKE ? OR note LIKE ?', "%#{query}%", "%#{query}%" - ).order('name').limit(limit).to_a + ).order('name').offset(offset).limit(limit).to_a # if only a few organizations are found, search for names of users if organizations.length <= 3 diff --git a/app/models/ticket/search.rb b/app/models/ticket/search.rb index ef8f487dc..998ab3653 100644 --- a/app/models/ticket/search.rb +++ b/app/models/ticket/search.rb @@ -35,6 +35,7 @@ search tickets via search index current_user: User.find(123), query: 'search something', limit: 15, + offset: 100, ) returns @@ -47,6 +48,7 @@ search tickets via search index current_user: User.find(123), query: 'search something', limit: 15, + offset: 100, full: false, ) @@ -77,6 +79,7 @@ search tickets via database ), }, limit: 15, + offset: 100, full: false, ) @@ -92,6 +95,7 @@ returns query = params[:query] condition = params[:condition] limit = params[:limit] || 12 + offset = params[:offset] || 0 current_user = params[:current_user] full = false if params[:full] == true || params[:full] == 'true' || !params.key?(:full) @@ -127,7 +131,7 @@ returns query_extention['bool']['must'].push access_condition - items = SearchIndexBackend.search(query, limit, 'Ticket', query_extention) + items = SearchIndexBackend.search(query, limit, 'Ticket', query_extention, offset) if !full ids = [] items.each do |item| @@ -156,6 +160,7 @@ returns .where('(tickets.title LIKE ? OR tickets.number LIKE ? OR ticket_articles.body LIKE ? OR ticket_articles.from LIKE ? OR ticket_articles.to LIKE ? OR ticket_articles.subject LIKE ?)', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" ) .joins(:articles) .order('tickets.created_at DESC') + .offset(offset) .limit(limit) else query_condition, bind_condition, tables = selector2sql(condition) @@ -164,6 +169,7 @@ returns .where(access_condition) .where(query_condition, *bind_condition) .order('tickets.created_at DESC') + .offset(offset) .limit(limit) end diff --git a/app/models/user/search.rb b/app/models/user/search.rb index 3a23d2775..9738b7cb1 100644 --- a/app/models/user/search.rb +++ b/app/models/user/search.rb @@ -37,6 +37,7 @@ search user result = User.search( query: 'some search term', limit: 15, + offset: 100, current_user: user_model, ) @@ -45,6 +46,7 @@ or with certain role_ids | permissions result = User.search( query: 'some search term', limit: 15, + offset: 100, current_user: user_model, role_ids: [1,2,3], permissions: ['ticket.agent'] @@ -61,6 +63,7 @@ returns # get params query = params[:query] limit = params[:limit] || 10 + offset = params[:offset] || 0 current_user = params[:current_user] # enable search only for agents and admins @@ -87,7 +90,7 @@ returns } query_extention['bool']['must'].push access_condition end - items = SearchIndexBackend.search(query, limit, 'User', query_extention) + items = SearchIndexBackend.search(query, limit, 'User', query_extention, offset) users = [] items.each do |item| user = User.lookup(id: item[:id]) @@ -103,11 +106,11 @@ returns users = if params[:role_ids] User.joins(:roles).where('roles.id' => params[:role_ids]).where( '(users.firstname LIKE ? OR users.lastname LIKE ? OR users.email LIKE ? OR users.login LIKE ?) AND users.id != 1', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" - ).order('updated_at DESC').limit(limit) + ).order('updated_at DESC').offset(offset).limit(limit) else User.where( '(firstname LIKE ? OR lastname LIKE ? OR email LIKE ? OR login LIKE ?) AND id != 1', "%#{query}%", "%#{query}%", "%#{query}%", "%#{query}%" - ).order('updated_at DESC').limit(limit) + ).order('updated_at DESC').offset(offset).limit(limit) end users end diff --git a/lib/search_index_backend.rb b/lib/search_index_backend.rb index 27dc5fa00..7c5e26f33 100644 --- a/lib/search_index_backend.rb +++ b/lib/search_index_backend.rb @@ -288,20 +288,20 @@ return search result =end - def self.search(query, limit = 10, index = nil, query_extention = {}) + def self.search(query, limit = 10, index = nil, query_extention = {}, from = 0) return [] if query.blank? if index.class == Array ids = [] index.each do |local_index| - local_ids = search_by_index(query, limit, local_index, query_extention) + local_ids = search_by_index(query, limit, local_index, query_extention, from) ids = ids.concat(local_ids) end return ids end - search_by_index(query, limit, index, query_extention) + search_by_index(query, limit, index, query_extention, from) end - def self.search_by_index(query, limit = 10, index = nil, query_extention = {}) + def self.search_by_index(query, limit = 10, index = nil, query_extention = {}, from) return [] if query.blank? url = build_url @@ -316,7 +316,7 @@ return search result '/_search' end data = {} - data['from'] = 0 + data['from'] = from data['size'] = limit data['sort'] = [