diff --git a/plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb b/plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb index d729cc0..a7f1ef8 100644 --- a/plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb +++ b/plugins/elasticsearch/controllers/elasticsearch_plugin_controller.rb @@ -12,8 +12,27 @@ class ElasticsearchPluginController < ApplicationController def search define_searchable_types define_search_fields_types + define_results + end + + def define_results + @query = params[:query] + @results = process_results + end - process_results + def define_searchable_types + @searchable_types = ElasticsearchHelper::searchable_types + @selected_type = (params[:selected_type]|| :all ).to_sym end + def define_search_fields_types + @search_filter_types = ElasticsearchHelper::search_filters + @selected_filter_field = (params[:selected_filter_field] || ElasticsearchHelper::search_filters.keys.first).to_sym + end + + private + +# def permit_params +# params.require(:per_page, :query) +# end end diff --git a/plugins/elasticsearch/helpers/elasticsearch_helper.rb b/plugins/elasticsearch/helpers/elasticsearch_helper.rb new file mode 100644 index 0000000..f1bd842 --- /dev/null +++ b/plugins/elasticsearch/helpers/elasticsearch_helper.rb @@ -0,0 +1,91 @@ +module ElasticsearchHelper + + def self.searchable_types + { + :all => { label: _("All Results")}, + :community => { label: _("Communities")}, + :event => { label: _("Events")}, + :person => { label: _("People")} + } + end + + def self.search_filters + { + :lexical => { label: _("Alphabetical Order")}, + :recent => { label: _("More Recent Order")}, + :access => { label: _("More accessed")} + } + end + + def fields_from_model + klass::SEARCHABLE_FIELDS.map do |key, value| + if value[:weight] + "#{key}^#{value[:weight]}" + else + "#{key}" + end + end + end + + def get_query text, klass=nil + query = {} + unless text.blank? + text = text.downcase + query = { + query: { + match_all: { + } + }, + filter: { + regexp: { + name: { + value: ".*" + text + ".*" } + } + }, + suggest: { + autocomplete: { + text: text, + term: { + field: "name", + suggest_mode: "always" + } + } + } + + } + end + query + end + + def process_results + selected_type = (params[:selected_type]|| :all).to_sym + if selected_type == :all + search_from_all_models + else + search_from_model selected_type + end + end + + def search_from_all_models + models = [] + query = get_query params[:query] + + ElasticsearchHelper::searchable_types.keys.each {| model | models.append( model.to_s.classify.constantize) if model != :all } + Elasticsearch::Model.search(query, models, size: default_per_page(params[:per_page])).page(params[:page]).records + end + + def search_from_model model + begin + klass = model.to_s.classify.constantize + query = get_query params[:query], klass + klass.search(query, size: default_per_page(params[:per_page])).page(params[:page]).records + rescue + [] + end + end + + def default_per_page per_page + per_page ||= 10 + end + +end diff --git a/plugins/elasticsearch/lib/elasticsearch_plugin/api.rb b/plugins/elasticsearch/lib/elasticsearch_plugin/api.rb index cb8a068..9326199 100644 --- a/plugins/elasticsearch/lib/elasticsearch_plugin/api.rb +++ b/plugins/elasticsearch/lib/elasticsearch_plugin/api.rb @@ -1,16 +1,20 @@ require_relative '../../helpers/elasticsearch_helper' - +require_relative 'entities' class ElasticsearchPlugin::API < Grape::API include Api::Helpers + helpers ElasticsearchHelper resource :search do get do - present target, :with => Api::Entities::Person + target = process_results + present target, + :with => Elasticsearch::Entities::Result, + :types => ElasticsearchHelper.searchable_types.except(:all).keys.map { |key| key.to_s.classify } end get 'types' do - types = {types: ElasticsearchHelper::SEARCHABLE_TYPES.stringify_keys.keys} + types = {types: ElasticsearchHelper::searchable_types.stringify_keys.keys} present types, with: Grape::Presenters::Presenter end diff --git a/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb b/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb new file mode 100644 index 0000000..92936da --- /dev/null +++ b/plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb @@ -0,0 +1,17 @@ +module Elasticsearch + module Entities + class Result < Api::Entity + root "results","result" + + expose :type do |object, options| + options[:types].detect { |type| type.to_s.upcase if object.is_a? (type.to_s.classify.constantize) } + end + + expose :name + + expose :author, if: lambda { |object,options| object.respond_to? 'author'} do |object, options| + object.author.present? ? object.author.name : "" + end + end + end +end diff --git a/plugins/elasticsearch/lib/ext/text_article.rb b/plugins/elasticsearch/lib/ext/text_article.rb index 8cc4f3a..2f3206f 100644 --- a/plugins/elasticsearch/lib/ext/text_article.rb +++ b/plugins/elasticsearch/lib/ext/text_article.rb @@ -4,8 +4,8 @@ require_relative '../elasticsearch_indexed_model' class TextArticle def self.control_fields { - :advertise => nil, - :published => nil, + :advertise => {}, + :published => {}, } end include ElasticsearchIndexedModel diff --git a/plugins/elasticsearch/lib/ext/uploaded_file.rb b/plugins/elasticsearch/lib/ext/uploaded_file.rb index b8425ba..187f8d1 100644 --- a/plugins/elasticsearch/lib/ext/uploaded_file.rb +++ b/plugins/elasticsearch/lib/ext/uploaded_file.rb @@ -4,8 +4,8 @@ require_relative '../elasticsearch_indexed_model' class UploadedFile def self.control_fields { - :advertise => nil, - :published => nil, + :advertise => {}, + :published => {}, } end include ElasticsearchIndexedModel diff --git a/plugins/elasticsearch/test/test_helper.rb b/plugins/elasticsearch/test/test_helper.rb index c4d2c7e..55f2b79 100644 --- a/plugins/elasticsearch/test/test_helper.rb +++ b/plugins/elasticsearch/test/test_helper.rb @@ -1,12 +1,17 @@ require 'test_helper' +require_relative '../../../test/api/test_helper.rb' -class ElasticsearchTestHelper < ActionController::TestCase +module ElasticsearchTestHelper def setup setup_environment + create_instances import_instancies end + def create_instances + end + def teardown indexed_models.each {|model| model.__elasticsearch__.client.indices.delete index: model.index_name @@ -16,9 +21,10 @@ class ElasticsearchTestHelper < ActionController::TestCase def import_instancies indexed_models.each {|model| model.__elasticsearch__.create_index! + sleep 2 model.import + sleep 1 } - sleep 2 end def setup_environment @@ -31,7 +37,7 @@ class ElasticsearchTestHelper < ActionController::TestCase end def indexed_fields model - model.mappings.to_hash[model.name.downcase.to_sym][:properties] + model.mappings.to_hash[model.name.underscore.to_sym][:properties] end end diff --git a/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb new file mode 100644 index 0000000..ce1b3f7 --- /dev/null +++ b/plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb @@ -0,0 +1,51 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" + +class ElasticsearchPluginApiTest < ActiveSupport::TestCase + + include ElasticsearchTestHelper + + def indexed_models + [Community, Person] + end + + def create_instances + 7.times.each {|index| create_user "person_#{index}"} + 4.times.each {|index| fast_create Community, name: "community_#{index}", created_at: Date.new } + end + + should 'show all types avaliable in /search/types endpoint' do + get "/api/v1/search/types" + json = JSON.parse(last_response.body) + assert_equal 200, last_response.status + assert_equal ElasticsearchHelper::searchable_types.stringify_keys.keys, json["types"] + end + + should 'respond with endpoint /search with more than 10 results' do + get "/api/v1/search" + json = JSON.parse(last_response.body) + assert_equal 200, last_response.status + assert_equal 10, json["results"].count + end + + should 'respond with query in downcase' do + get "/api/v1/search?query=person_" + json = JSON.parse(last_response.body) + assert_equal 200, last_response.status + assert_equal 7, json["results"].count + end + + should 'respond with query in upcase' do + get "/api/v1/search?query=PERSON_" + json = JSON.parse(last_response.body) + assert_equal 200, last_response.status + assert_equal 7, json["results"].count + end + + should 'respond with selected_type' do + get "/api/v1/search?selected_type=community" + json = JSON.parse(last_response.body) + assert_equal 200, last_response.status + assert_equal 4, json["results"].count + end + +end diff --git a/plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb b/plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb index 30ab344..76a2d55 100644 --- a/plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb +++ b/plugins/elasticsearch/test/unit/controllers/elasticsearch_plugin_controller_test.rb @@ -1,20 +1,13 @@ require "#{File.dirname(__FILE__)}/../../test_helper" -class ElasticsearchPluginControllerTest < ElasticsearchTestHelper +class ElasticsearchPluginControllerTest < ActionController::TestCase + + include ElasticsearchTestHelper def indexed_models [Community, Person] end - def setup - create_instances - super - end - - def teardown - super - end - def create_instances create_people create_communities diff --git a/plugins/elasticsearch/test/unit/elasticsearch_test.rb b/plugins/elasticsearch/test/unit/elasticsearch_test.rb index f10e336..75fd0a2 100644 --- a/plugins/elasticsearch/test/unit/elasticsearch_test.rb +++ b/plugins/elasticsearch/test/unit/elasticsearch_test.rb @@ -1,6 +1,6 @@ require "#{File.dirname(__FILE__)}/../test_helper" -class ElasticsearchTest < ElasticsearchTestHelper +class ElasticsearchTest < ActionController::TestCase should 'be return yellow for health status' do cluster = Elasticsearch::Model.client.cluster diff --git a/plugins/elasticsearch/test/unit/models/community_test.rb b/plugins/elasticsearch/test/unit/models/community_test.rb index 4ee9208..74cac82 100644 --- a/plugins/elasticsearch/test/unit/models/community_test.rb +++ b/plugins/elasticsearch/test/unit/models/community_test.rb @@ -1,6 +1,8 @@ require "#{File.dirname(__FILE__)}/../../test_helper" -class CommunityTest < ElasticsearchTestHelper +class CommunityTest < ActionController::TestCase + + include ElasticsearchTestHelper def indexed_models [Community] diff --git a/plugins/elasticsearch/test/unit/models/event_test.rb b/plugins/elasticsearch/test/unit/models/event_test.rb index 4b0da33..b857896 100644 --- a/plugins/elasticsearch/test/unit/models/event_test.rb +++ b/plugins/elasticsearch/test/unit/models/event_test.rb @@ -1,6 +1,8 @@ require "#{File.dirname(__FILE__)}/../../test_helper" -class EventTest < ElasticsearchTestHelper +class EventTest < ActionController::TestCase + + include ElasticsearchTestHelper def indexed_models [Event] diff --git a/plugins/elasticsearch/test/unit/models/person_test.rb b/plugins/elasticsearch/test/unit/models/person_test.rb index 0be2861..a8cafc5 100644 --- a/plugins/elasticsearch/test/unit/models/person_test.rb +++ b/plugins/elasticsearch/test/unit/models/person_test.rb @@ -1,6 +1,8 @@ require "#{File.dirname(__FILE__)}/../../test_helper" -class PersonTest < ElasticsearchTestHelper +class PersonTest < ActionController::TestCase + + include ElasticsearchTestHelper def indexed_models [Person] diff --git a/plugins/elasticsearch/test/unit/models/text_article_test.rb b/plugins/elasticsearch/test/unit/models/text_article_test.rb new file mode 100644 index 0000000..937b77f --- /dev/null +++ b/plugins/elasticsearch/test/unit/models/text_article_test.rb @@ -0,0 +1,28 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" + +class TextArticleTest < ActionController::TestCase + + include ElasticsearchTestHelper + + def indexed_models + [TextArticle] + end + + def setup + super + end + + should 'index searchable fields for TextArticle model' do + TextArticle::SEARCHABLE_FIELDS.each do |key, value| + assert_includes indexed_fields(TextArticle), key + end + end + + should 'index control fields for TextArticle model' do + TextArticle::control_fields.each do |key, value| + assert_includes indexed_fields(TextArticle), key + assert_includes indexed_fields(TextArticle)[key][:type], value[:type] || 'string' + end + end + +end diff --git a/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb b/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb new file mode 100644 index 0000000..04bd842 --- /dev/null +++ b/plugins/elasticsearch/test/unit/models/uploaded_file_test.rb @@ -0,0 +1,28 @@ +require "#{File.dirname(__FILE__)}/../../test_helper" + +class UploadedFileTest < ActionController::TestCase + + include ElasticsearchTestHelper + + def indexed_models + [UploadedFile] + end + + def setup + super + end + + should 'index searchable fields for UploadedFile model' do + UploadedFile::SEARCHABLE_FIELDS.each do |key, value| + assert_includes indexed_fields(UploadedFile), key + end + end + + should 'index control fields for UploadedFile model' do + UploadedFile::control_fields.each do |key, value| + assert_includes indexed_fields(UploadedFile), key + assert_includes indexed_fields(UploadedFile)[key][:type], value[:type].presence || 'string' + end + end + +end -- libgit2 0.21.2