Commit e16d0e8c31a79f8aa309f52e14c6fb20d57b181e

Authored by Macartur Sousa
1 parent aedd0f8e
Exists in elasticsearch_sort

Refactored controller and searching by api

Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb
... ... @@ -12,8 +12,27 @@ class ElasticsearchPluginController &lt; ApplicationController
12 12 def search
13 13 define_searchable_types
14 14 define_search_fields_types
  15 + define_results
  16 + end
  17 +
  18 + def define_results
  19 + @query = params[:query]
  20 + @results = process_results
  21 + end
15 22  
16   - process_results
  23 + def define_searchable_types
  24 + @searchable_types = ElasticsearchHelper::searchable_types
  25 + @selected_type = (params[:selected_type]|| :all ).to_sym
17 26 end
18 27  
  28 + def define_search_fields_types
  29 + @search_filter_types = ElasticsearchHelper::search_filters
  30 + @selected_filter_field = (params[:selected_filter_field] || ElasticsearchHelper::search_filters.keys.first).to_sym
  31 + end
  32 +
  33 + private
  34 +
  35 +# def permit_params
  36 +# params.require(:per_page, :query)
  37 +# end
19 38 end
... ...
plugins/elasticsearch/helpers/elasticsearch_helper.rb 0 → 100644
... ... @@ -0,0 +1,91 @@
  1 +module ElasticsearchHelper
  2 +
  3 + def self.searchable_types
  4 + {
  5 + :all => { label: _("All Results")},
  6 + :community => { label: _("Communities")},
  7 + :event => { label: _("Events")},
  8 + :person => { label: _("People")}
  9 + }
  10 + end
  11 +
  12 + def self.search_filters
  13 + {
  14 + :lexical => { label: _("Alphabetical Order")},
  15 + :recent => { label: _("More Recent Order")},
  16 + :access => { label: _("More accessed")}
  17 + }
  18 + end
  19 +
  20 + def fields_from_model
  21 + klass::SEARCHABLE_FIELDS.map do |key, value|
  22 + if value[:weight]
  23 + "#{key}^#{value[:weight]}"
  24 + else
  25 + "#{key}"
  26 + end
  27 + end
  28 + end
  29 +
  30 + def get_query text, klass=nil
  31 + query = {}
  32 + unless text.blank?
  33 + text = text.downcase
  34 + query = {
  35 + query: {
  36 + match_all: {
  37 + }
  38 + },
  39 + filter: {
  40 + regexp: {
  41 + name: {
  42 + value: ".*" + text + ".*" }
  43 + }
  44 + },
  45 + suggest: {
  46 + autocomplete: {
  47 + text: text,
  48 + term: {
  49 + field: "name",
  50 + suggest_mode: "always"
  51 + }
  52 + }
  53 + }
  54 +
  55 + }
  56 + end
  57 + query
  58 + end
  59 +
  60 + def process_results
  61 + selected_type = (params[:selected_type]|| :all).to_sym
  62 + if selected_type == :all
  63 + search_from_all_models
  64 + else
  65 + search_from_model selected_type
  66 + end
  67 + end
  68 +
  69 + def search_from_all_models
  70 + models = []
  71 + query = get_query params[:query]
  72 +
  73 + ElasticsearchHelper::searchable_types.keys.each {| model | models.append( model.to_s.classify.constantize) if model != :all }
  74 + Elasticsearch::Model.search(query, models, size: default_per_page(params[:per_page])).page(params[:page]).records
  75 + end
  76 +
  77 + def search_from_model model
  78 + begin
  79 + klass = model.to_s.classify.constantize
  80 + query = get_query params[:query], klass
  81 + klass.search(query, size: default_per_page(params[:per_page])).page(params[:page]).records
  82 + rescue
  83 + []
  84 + end
  85 + end
  86 +
  87 + def default_per_page per_page
  88 + per_page ||= 10
  89 + end
  90 +
  91 +end
... ...
plugins/elasticsearch/lib/elasticsearch_plugin/api.rb
1 1 require_relative '../../helpers/elasticsearch_helper'
2   -
  2 +require_relative 'entities'
3 3  
4 4 class ElasticsearchPlugin::API < Grape::API
5 5 include Api::Helpers
  6 + helpers ElasticsearchHelper
6 7  
7 8 resource :search do
8 9 get do
9   - present target, :with => Api::Entities::Person
  10 + target = process_results
  11 + present target,
  12 + :with => Elasticsearch::Entities::Result,
  13 + :types => ElasticsearchHelper.searchable_types.except(:all).keys.map { |key| key.to_s.classify }
10 14 end
11 15  
12 16 get 'types' do
13   - types = {types: ElasticsearchHelper::SEARCHABLE_TYPES.stringify_keys.keys}
  17 + types = {types: ElasticsearchHelper::searchable_types.stringify_keys.keys}
14 18 present types, with: Grape::Presenters::Presenter
15 19 end
16 20  
... ...
plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb 0 → 100644
... ... @@ -0,0 +1,17 @@
  1 +module Elasticsearch
  2 + module Entities
  3 + class Result < Api::Entity
  4 + root "results","result"
  5 +
  6 + expose :type do |object, options|
  7 + options[:types].detect { |type| type.to_s.upcase if object.is_a? (type.to_s.classify.constantize) }
  8 + end
  9 +
  10 + expose :name
  11 +
  12 + expose :author, if: lambda { |object,options| object.respond_to? 'author'} do |object, options|
  13 + object.author.present? ? object.author.name : ""
  14 + end
  15 + end
  16 + end
  17 +end
... ...
plugins/elasticsearch/lib/ext/text_article.rb
... ... @@ -4,8 +4,8 @@ require_relative &#39;../elasticsearch_indexed_model&#39;
4 4 class TextArticle
5 5 def self.control_fields
6 6 {
7   - :advertise => nil,
8   - :published => nil,
  7 + :advertise => {},
  8 + :published => {},
9 9 }
10 10 end
11 11 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/lib/ext/uploaded_file.rb
... ... @@ -4,8 +4,8 @@ require_relative &#39;../elasticsearch_indexed_model&#39;
4 4 class UploadedFile
5 5 def self.control_fields
6 6 {
7   - :advertise => nil,
8   - :published => nil,
  7 + :advertise => {},
  8 + :published => {},
9 9 }
10 10 end
11 11 include ElasticsearchIndexedModel
... ...
plugins/elasticsearch/test/test_helper.rb
1 1 require 'test_helper'
  2 +require_relative '../../../test/api/test_helper.rb'
2 3  
3   -class ElasticsearchTestHelper < ActionController::TestCase
  4 +module ElasticsearchTestHelper
4 5  
5 6 def setup
6 7 setup_environment
  8 + create_instances
7 9 import_instancies
8 10 end
9 11  
  12 + def create_instances
  13 + end
  14 +
10 15 def teardown
11 16 indexed_models.each {|model|
12 17 model.__elasticsearch__.client.indices.delete index: model.index_name
... ... @@ -16,9 +21,10 @@ class ElasticsearchTestHelper &lt; ActionController::TestCase
16 21 def import_instancies
17 22 indexed_models.each {|model|
18 23 model.__elasticsearch__.create_index!
  24 + sleep 2
19 25 model.import
  26 + sleep 1
20 27 }
21   - sleep 2
22 28 end
23 29  
24 30 def setup_environment
... ... @@ -31,7 +37,7 @@ class ElasticsearchTestHelper &lt; ActionController::TestCase
31 37 end
32 38  
33 39 def indexed_fields model
34   - model.mappings.to_hash[model.name.downcase.to_sym][:properties]
  40 + model.mappings.to_hash[model.name.underscore.to_sym][:properties]
35 41 end
36 42  
37 43 end
... ...
plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class ElasticsearchPluginApiTest < ActiveSupport::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Community, Person]
  9 + end
  10 +
  11 + def create_instances
  12 + 7.times.each {|index| create_user "person_#{index}"}
  13 + 4.times.each {|index| fast_create Community, name: "community_#{index}", created_at: Date.new }
  14 + end
  15 +
  16 + should 'show all types avaliable in /search/types endpoint' do
  17 + get "/api/v1/search/types"
  18 + json = JSON.parse(last_response.body)
  19 + assert_equal 200, last_response.status
  20 + assert_equal ElasticsearchHelper::searchable_types.stringify_keys.keys, json["types"]
  21 + end
  22 +
  23 + should 'respond with endpoint /search with more than 10 results' do
  24 + get "/api/v1/search"
  25 + json = JSON.parse(last_response.body)
  26 + assert_equal 200, last_response.status
  27 + assert_equal 10, json["results"].count
  28 + end
  29 +
  30 + should 'respond with query in downcase' do
  31 + get "/api/v1/search?query=person_"
  32 + json = JSON.parse(last_response.body)
  33 + assert_equal 200, last_response.status
  34 + assert_equal 7, json["results"].count
  35 + end
  36 +
  37 + should 'respond with query in upcase' do
  38 + get "/api/v1/search?query=PERSON_"
  39 + json = JSON.parse(last_response.body)
  40 + assert_equal 200, last_response.status
  41 + assert_equal 7, json["results"].count
  42 + end
  43 +
  44 + should 'respond with selected_type' do
  45 + get "/api/v1/search?selected_type=community"
  46 + json = JSON.parse(last_response.body)
  47 + assert_equal 200, last_response.status
  48 + assert_equal 4, json["results"].count
  49 + end
  50 +
  51 +end
... ...
plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb
1 1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2  
3   -class ElasticsearchPluginControllerTest < ElasticsearchTestHelper
  3 +class ElasticsearchPluginControllerTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
4 6  
5 7 def indexed_models
6 8 [Community, Person]
7 9 end
8 10  
9   - def setup
10   - create_instances
11   - super
12   - end
13   -
14   - def teardown
15   - super
16   - end
17   -
18 11 def create_instances
19 12 create_people
20 13 create_communities
... ...
plugins/elasticsearch/test/unit/elasticsearch_test.rb
1 1 require "#{File.dirname(__FILE__)}/../test_helper"
2 2  
3   -class ElasticsearchTest < ElasticsearchTestHelper
  3 +class ElasticsearchTest < ActionController::TestCase
4 4  
5 5 should 'be return yellow for health status' do
6 6 cluster = Elasticsearch::Model.client.cluster
... ...
plugins/elasticsearch/test/unit/models/community_test.rb
1 1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2  
3   -class CommunityTest < ElasticsearchTestHelper
  3 +class CommunityTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
4 6  
5 7 def indexed_models
6 8 [Community]
... ...
plugins/elasticsearch/test/unit/models/event_test.rb
1 1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2  
3   -class EventTest < ElasticsearchTestHelper
  3 +class EventTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
4 6  
5 7 def indexed_models
6 8 [Event]
... ...
plugins/elasticsearch/test/unit/models/person_test.rb
1 1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2  
3   -class PersonTest < ElasticsearchTestHelper
  3 +class PersonTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
4 6  
5 7 def indexed_models
6 8 [Person]
... ...
plugins/elasticsearch/test/unit/models/text_article_test.rb 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class TextArticleTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [TextArticle]
  9 + end
  10 +
  11 + def setup
  12 + super
  13 + end
  14 +
  15 + should 'index searchable fields for TextArticle model' do
  16 + TextArticle::SEARCHABLE_FIELDS.each do |key, value|
  17 + assert_includes indexed_fields(TextArticle), key
  18 + end
  19 + end
  20 +
  21 + should 'index control fields for TextArticle model' do
  22 + TextArticle::control_fields.each do |key, value|
  23 + assert_includes indexed_fields(TextArticle), key
  24 + assert_includes indexed_fields(TextArticle)[key][:type], value[:type] || 'string'
  25 + end
  26 + end
  27 +
  28 +end
... ...
plugins/elasticsearch/test/unit/models/uploaded_file_test.rb 0 → 100644
... ... @@ -0,0 +1,28 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class UploadedFileTest < ActionController::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [UploadedFile]
  9 + end
  10 +
  11 + def setup
  12 + super
  13 + end
  14 +
  15 + should 'index searchable fields for UploadedFile model' do
  16 + UploadedFile::SEARCHABLE_FIELDS.each do |key, value|
  17 + assert_includes indexed_fields(UploadedFile), key
  18 + end
  19 + end
  20 +
  21 + should 'index control fields for UploadedFile model' do
  22 + UploadedFile::control_fields.each do |key, value|
  23 + assert_includes indexed_fields(UploadedFile), key
  24 + assert_includes indexed_fields(UploadedFile)[key][:type], value[:type].presence || 'string'
  25 + end
  26 + end
  27 +
  28 +end
... ...