Commit aaa5d1b8fec04f9401bb3fff7459c3f253fdc908

Authored by Macartur Sousa
1 parent 65882f09
Exists in elasticsearch_sort

Refactored elasticsearch_plugin and elasticsearch_api

Signed-off-by: Macartur Sousa <macartur.sc@gmail.com>
plugins/elasticsearch/helpers/elasticsearch_helper.rb
... ... @@ -19,42 +19,16 @@ module ElasticsearchHelper
19 19 }
20 20 end
21 21  
22   - def fields_from_models klasses
23   - fields = Set.new
24   - klasses.each do |klass|
25   - klass::SEARCHABLE_FIELDS.map do |key, value|
26   - if value and value[:weight]
27   - fields.add "#{key}^#{value[:weight]}"
28   - else
29   - fields.add "#{key}"
30   - end
31   - end
32   - end
33   - fields.to_a
34   - end
35   -
36   - def get_sort_by sort_by
37   - case sort_by
38   - when "lexical"
39   - { "name.raw" => {"order" => "asc" }}
40   - when "recent"
41   - { "created_at" => {"order" => "desc"}}
42   - end
43   - end
44   -
45 22 def process_results
46   - selected_type = (params[:selected_type]|| :all).to_sym
47   - if selected_type == :all
48   - search_from_all_models
49   - else
50   - search_from_model selected_type
51   - end
  23 + selected_type = (params[:selected_type].presence|| :all).to_sym
  24 + selected_type == :all ? search_from_all_models : search_from_model(selected_type)
52 25 end
53 26  
  27 + private
  28 +
54 29 def search_from_all_models
55 30 query = get_query params[:query], sort_by: get_sort_by(params[:selected_filter])
56   - models = searchable_models
57   - Elasticsearch::Model.search(query, models, size: default_per_page(params[:per_page])).page(params[:page]).records
  31 + Elasticsearch::Model.search(query,searchable_models, size: default_per_page(params[:per_page])).page(params[:page]).records
58 32 end
59 33  
60 34 def search_from_model model
... ... @@ -68,17 +42,28 @@ module ElasticsearchHelper
68 42 end
69 43 end
70 44  
71   - def default_per_page per_page
  45 + def default_per_page per_page=nil
72 46 per_page ||= 10
73 47 end
74 48  
75   - private
  49 + def get_sort_by sort_by
  50 + case sort_by
  51 + when "lexical"
  52 + { "name.raw" => {"order" => "asc" }}
  53 + when "recent"
  54 + { "created_at" => {"order" => "desc"}}
  55 + end
  56 + end
76 57  
77 58 def searchable_models
78   - ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize }
  59 + begin
  60 + ElasticsearchHelper::searchable_types.except(:all).keys.map { | model | model.to_s.classify.constantize }
  61 + rescue
  62 + []
  63 + end
79 64 end
80 65  
81   - def query_method expression, fields
  66 + def query_method expression="", fields=[]
82 67 query_exp = {}
83 68 if expression.blank?
84 69 query_exp = {
... ... @@ -107,8 +92,21 @@ module ElasticsearchHelper
107 92 }
108 93  
109 94 query[:sort] = [sort_by,"_score"] if sort_by
110   -
111 95 query
112 96 end
113 97  
  98 + def fields_from_models klasses
  99 + fields = Set.new
  100 + klasses.each do |klass|
  101 + klass::SEARCHABLE_FIELDS.map do |key, value|
  102 + if value and value[:weight]
  103 + fields.add "#{key}^#{value[:weight]}"
  104 + else
  105 + fields.add "#{key}"
  106 + end
  107 + end
  108 + end
  109 + fields.to_a
  110 + end
  111 +
114 112 end
... ...
plugins/elasticsearch/lib/elasticsearch_plugin/entities.rb
1 1 module Elasticsearch
2 2 module Entities
  3 +
3 4 class Result < Api::Entity
4 5 root "results","result"
5 6  
... ... @@ -7,11 +8,24 @@ module Elasticsearch
7 8 options[:types].detect { |type| type.to_s.upcase if object.is_a? (type.to_s.classify.constantize) }
8 9 end
9 10  
  11 + expose :id
10 12 expose :name
11 13  
12 14 expose :author, if: lambda { |object,options| object.respond_to? 'author'} do |object, options|
13 15 object.author.present? ? object.author.name : ""
14 16 end
  17 +
  18 + expose :description, if: lambda { |object,options| object.respond_to? 'description'} do |object, options|
  19 + object.description.present? ? object.description : ""
  20 + end
  21 +
  22 + expose :abstract, if: lambda { |object,options| object.respond_to? 'abstract'} do |object, options|
  23 + object.abstract.present? ? object.abstract : ""
  24 + end
  25 +
  26 + expose :created_at, :format_with => :timestamp
  27 + expose :updated_at, :format_with => :timestamp
15 28 end
  29 +
16 30 end
17 31 end
... ...
plugins/elasticsearch/test/unit/api/elasticsearch_plugin_api_test.rb
... ... @@ -10,7 +10,7 @@ class ElasticsearchPluginApiTest &lt; ActiveSupport::TestCase
10 10  
11 11 def create_instances
12 12 7.times.each {|index| create_user "person #{index}"}
13   - 4.times.each {|index| fast_create Community, name: "community #{index}", created_at: Date.new }
  13 + 4.times.each {|index| fast_create Community, name: "community #{index}" }
14 14 end
15 15  
16 16 should 'show all types avaliable in /search/types endpoint' do
... ... @@ -47,5 +47,4 @@ class ElasticsearchPluginApiTest &lt; ActiveSupport::TestCase
47 47 assert_equal 200, last_response.status
48 48 assert_equal 4, json["results"].count
49 49 end
50   -
51 50 end
... ...
plugins/elasticsearch/test/unit/api/elasticsearch_plugin_entities_test.rb 0 → 100644
... ... @@ -0,0 +1,122 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +
  3 +class ElasticsearchPluginEntitiesTest < ActiveSupport::TestCase
  4 +
  5 + include ElasticsearchTestHelper
  6 +
  7 + def indexed_models
  8 + [Person,TextArticle,UploadedFile,Community,Event]
  9 + end
  10 +
  11 + def create_instances
  12 + user = create_user "sample person"
  13 +
  14 + fast_create Community, name: "sample community", created_at: 10.days.ago,updated_at: 5.days.ago
  15 + fast_create UploadedFile, name: "sample uploadedfile", created_at: 3.days.ago, updated_at: 1.days.ago, author_id: user.person.id, abstract: "sample abstract"
  16 + fast_create Event, name: "sample event", created_at: 20.days.ago, updated_at: 5.days.ago, author_id: user.person.id, abstract: "sample abstract"
  17 +
  18 + fast_create RawHTMLArticle, name: "sample raw html article", created_at: 15.days.ago ,updated_at: 5.days.ago, author_id: user.person.id
  19 + fast_create TinyMceArticle, name: "sample tiny mce article", created_at: 5.days.ago, updated_at: 5.days.ago, author_id: user.person.id
  20 + end
  21 +
  22 + should 'show attributes from person' do
  23 + params = {:selected_type => "person" }
  24 + get "/api/v1/search?#{params.to_query}"
  25 + json= JSON.parse(last_response.body)
  26 +
  27 + expected_person = Person.find_by name: "sample person"
  28 +
  29 + assert_equal 200, last_response.status
  30 + assert_equal expected_person.id, json['results'][0]['id']
  31 + assert_equal expected_person.name, json['results'][0]['name']
  32 + assert_equal expected_person.type, json['results'][0]['type']
  33 + assert_equal "", json['results'][0]['description']
  34 + assert_equal expected_person.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at']
  35 + assert_equal expected_person.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at']
  36 + end
  37 +
  38 + should 'show attributes from community' do
  39 + params = {:selected_type => "community" }
  40 + get "/api/v1/search?#{params.to_query}"
  41 + json= JSON.parse(last_response.body)
  42 +
  43 + expected_community = Community.find_by name: "sample community"
  44 +
  45 + assert_equal 200, last_response.status
  46 + assert_equal expected_community.id, json['results'][0]['id']
  47 + assert_equal expected_community.name, json['results'][0]['name']
  48 + assert_equal expected_community.type, json['results'][0]['type']
  49 + assert_equal "", json['results'][0]['description']
  50 + assert_equal expected_community.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['created_at']
  51 + assert_equal expected_community.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][0]['updated_at']
  52 + end
  53 +
  54 + should 'show attributes from text_article' do
  55 + params = {:selected_type => "text_article" }
  56 + get "/api/v1/search?#{params.to_query}"
  57 +
  58 + json= JSON.parse(last_response.body)
  59 +
  60 + assert_equal 200, last_response.status
  61 +
  62 + expected_text_articles = TextArticle.all
  63 +
  64 + expected_text_articles.each_with_index {|object,index|
  65 + assert_equal object.id, json['results'][index]['id']
  66 + assert_equal object.name, json['results'][index]['name']
  67 + assert_equal "TextArticle", json['results'][index]['type']
  68 +
  69 + expected_author = (object.author.nil?) ? "" : object.author.name
  70 +
  71 + assert_equal expected_author, json['results'][index]['author']
  72 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  73 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  74 + }
  75 + end
  76 +
  77 + should 'show attributes from uploaded_file' do
  78 + params = {:selected_type => "uploaded_file"}
  79 + get "/api/v1/search?#{params.to_query}"
  80 +
  81 + json= JSON.parse(last_response.body)
  82 +
  83 + assert_equal 200, last_response.status
  84 +
  85 + expected_uploaded_files = UploadedFile.all
  86 + expected_uploaded_files.each_with_index {|object,index|
  87 + assert_equal object.id, json['results'][index]['id']
  88 + assert_equal object.name, json['results'][index]['name']
  89 + assert_equal object.abstract, json['results'][index]['abstract']
  90 + assert_equal "UploadedFile", json['results'][index]['type']
  91 +
  92 + expected_author = (object.author.nil?) ? "" : object.author.name
  93 + assert_equal expected_author, json['results'][index]['author']
  94 +
  95 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  96 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  97 + }
  98 + end
  99 +
  100 + should 'show attributes from event' do
  101 + params = {:selected_type => "event"}
  102 + get "/api/v1/search?#{params.to_query}"
  103 +
  104 + json= JSON.parse(last_response.body)
  105 +
  106 + assert_equal 200, last_response.status
  107 + expected_events = Event.all
  108 + expected_events.each_with_index {|object,index|
  109 + assert_equal object.id, json['results'][index]['id']
  110 + assert_equal object.name, json['results'][index]['name']
  111 + assert_equal object.abstract, json['results'][index]['abstract']
  112 + assert_equal "Event", json['results'][index]['type']
  113 +
  114 + expected_author = (object.author.nil?) ? "" : object.author.name
  115 + assert_equal expected_author, json['results'][index]['author']
  116 +
  117 + assert_equal object.created_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['created_at']
  118 + assert_equal object.updated_at.strftime("%Y/%m/%d %H:%M:%S"), json['results'][index]['updated_at']
  119 + }
  120 + end
  121 +
  122 +end
... ...
plugins/elasticsearch/test/unit/helpers/elasticsearch_helper_test.rb 0 → 100644
... ... @@ -0,0 +1,90 @@
  1 +require "#{File.dirname(__FILE__)}/../../test_helper"
  2 +require_relative '../../../helpers/elasticsearch_helper.rb'
  3 +
  4 +class ElasticsearchHelperTest < ActiveSupport::TestCase
  5 +
  6 + include ElasticsearchTestHelper
  7 + include ElasticsearchHelper
  8 +
  9 + attr_accessor :params
  10 +
  11 + def indexed_models
  12 + [Person,TextArticle,UploadedFile,Community,Event]
  13 + end
  14 +
  15 + def create_instances
  16 + create_user "Jose Abreu"
  17 + create_user "Joao Abreu"
  18 + create_user "Joana Abreu"
  19 + create_user "Ana Abreu"
  20 + end
  21 +
  22 + should 'return default_per_page when nil is passed' do
  23 + assert_not_nil default_per_page nil
  24 + assert_equal 10, default_per_page(nil)
  25 + end
  26 +
  27 + should 'return default_per_page when per_page is passed' do
  28 + assert_equal 15, default_per_page(15)
  29 + end
  30 +
  31 + should 'have indexed_models in searchable_models' do
  32 + assert_equivalent indexed_models, searchable_models
  33 + end
  34 +
  35 + should 'return match_all if expression is blank' do
  36 + assert_includes query_method.keys, :match_all
  37 + end
  38 +
  39 + should 'return multi_match if expression is valid' do
  40 +
  41 + query= "my_query"
  42 + fields = ['name','login']
  43 + result = query_method(query,fields)
  44 +
  45 + assert_includes result.keys, :multi_match
  46 + assert_includes result[:multi_match][:query], query
  47 + assert_equivalent result[:multi_match][:fields], fields
  48 + end
  49 +
  50 +
  51 + should 'return fields from models using weight' do
  52 + class StubClass
  53 + SEARCHABLE_FIELDS = {:name => {:weight => 10},
  54 + :login => {:weight => 20},
  55 + :description => {:weight => 2}}
  56 + end
  57 +
  58 + expected = ["name^10", "login^20", "description^2"]
  59 + assert_equivalent expected, fields_from_models([StubClass])
  60 + end
  61 +
  62 + should 'search from model Person sorted by Alphabetic' do
  63 + self.params= {:selected_type => 'person',
  64 + :selected_filter => 'lexical',
  65 + :per_page => 4}
  66 +
  67 + result = process_results
  68 + assert_equal ["Ana Abreu","Joana Abreu","Joao Abreu","Jose Abreu"], result.map(&:name)
  69 + end
  70 +
  71 + should 'search from model Person sorted by More Recent' do
  72 + self.params= {:selected_type => 'person',
  73 + :selected_filter => 'more_recent',
  74 + :per_page => 4}
  75 +
  76 + result = process_results
  77 + assert_equal ["Jose Abreu","Joao Abreu","Joana Abreu","Ana Abreu"],result.map(&:name)
  78 + end
  79 +
  80 + should 'search from model Person sorted by Relevance' do
  81 + self.params= {:selected_type => 'person',
  82 + :selected_filter => 'more_recent',
  83 + :query => 'JOAO ABREU',
  84 + :per_page => 4}
  85 +
  86 + result = process_results
  87 + assert_equal ["Joao Abreu","Jose Abreu","Joana Abreu","Ana Abreu"],result.map(&:name)
  88 + end
  89 +
  90 +end
... ...
plugins/elasticsearch/test/unit/models/community_test.rb
... ... @@ -8,10 +8,6 @@ class CommunityTest &lt; ActionController::TestCase
8 8 [Community]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Community model' do
16 12 Community::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Community), key
... ...
plugins/elasticsearch/test/unit/models/event_test.rb
... ... @@ -8,10 +8,6 @@ class EventTest &lt; ActionController::TestCase
8 8 [Event]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Event model' do
16 12 Event::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Event), key
... ...
plugins/elasticsearch/test/unit/models/person_test.rb
... ... @@ -8,10 +8,6 @@ class PersonTest &lt; ActionController::TestCase
8 8 [Person]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for Person model' do
16 12 Person::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(Person), key
... ... @@ -24,5 +20,4 @@ class PersonTest &lt; ActionController::TestCase
24 20 assert_includes indexed_fields(Person)[key][:type], value[:type] || 'string'
25 21 end
26 22 end
27   -
28 23 end
... ...
plugins/elasticsearch/test/unit/models/text_article_test.rb
... ... @@ -8,10 +8,6 @@ class TextArticleTest &lt; ActionController::TestCase
8 8 [TextArticle]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for TextArticle model' do
16 12 TextArticle::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(TextArticle), key
... ...
plugins/elasticsearch/test/unit/models/uploaded_file_test.rb
... ... @@ -8,10 +8,6 @@ class UploadedFileTest &lt; ActionController::TestCase
8 8 [UploadedFile]
9 9 end
10 10  
11   - def setup
12   - super
13   - end
14   -
15 11 should 'index searchable fields for UploadedFile model' do
16 12 UploadedFile::SEARCHABLE_FIELDS.each do |key, value|
17 13 assert_includes indexed_fields(UploadedFile), key
... ...
plugins/elasticsearch/views/elasticsearch_plugin/_person_display.html.erb
... ... @@ -7,7 +7,6 @@
7 7 <div class="body">
8 8 <h2><%= link_to person.name, person.url %></h2>
9 9 <p><%= person.description %></p>
10   - <%= person.created_at %>
11 10 </div>
12 11 </div>
13 12 </div>
... ...