mm_es_search 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/.gitignore +4 -0
  2. data/.project +18 -0
  3. data/Gemfile +4 -0
  4. data/Rakefile +1 -0
  5. data/lib/mm_es_search/api/facet/abstract_facet.rb +28 -0
  6. data/lib/mm_es_search/api/facet/date_histogram_facet.rb +11 -0
  7. data/lib/mm_es_search/api/facet/filter_facet.rb +9 -0
  8. data/lib/mm_es_search/api/facet/geo_distance_facet.rb +9 -0
  9. data/lib/mm_es_search/api/facet/histogram_facet.rb +9 -0
  10. data/lib/mm_es_search/api/facet/query_facet.rb +9 -0
  11. data/lib/mm_es_search/api/facet/range_facet.rb +36 -0
  12. data/lib/mm_es_search/api/facet/range_facet_row.rb +97 -0
  13. data/lib/mm_es_search/api/facet/range_item.rb +17 -0
  14. data/lib/mm_es_search/api/facet/statistical_facet.rb +33 -0
  15. data/lib/mm_es_search/api/facet/statistical_facet_result.rb +36 -0
  16. data/lib/mm_es_search/api/facet/terms_facet.rb +62 -0
  17. data/lib/mm_es_search/api/facet/terms_facet_row.rb +35 -0
  18. data/lib/mm_es_search/api/facet/terms_stats_facet.rb +9 -0
  19. data/lib/mm_es_search/api/highlight/result_highlight.rb +40 -0
  20. data/lib/mm_es_search/api/query/abstract_filter.rb +15 -0
  21. data/lib/mm_es_search/api/query/abstract_query.rb +48 -0
  22. data/lib/mm_es_search/api/query/and_filter.rb +9 -0
  23. data/lib/mm_es_search/api/query/bool_filter.rb +11 -0
  24. data/lib/mm_es_search/api/query/bool_query.rb +67 -0
  25. data/lib/mm_es_search/api/query/constant_score_query.rb +31 -0
  26. data/lib/mm_es_search/api/query/custom_filters_score_query.rb +52 -0
  27. data/lib/mm_es_search/api/query/custom_score_query.rb +31 -0
  28. data/lib/mm_es_search/api/query/dismax_query.rb +29 -0
  29. data/lib/mm_es_search/api/query/filtered_query.rb +30 -0
  30. data/lib/mm_es_search/api/query/has_child_filter.rb +11 -0
  31. data/lib/mm_es_search/api/query/has_child_query.rb +25 -0
  32. data/lib/mm_es_search/api/query/has_parent_filter.rb +11 -0
  33. data/lib/mm_es_search/api/query/has_parent_query.rb +25 -0
  34. data/lib/mm_es_search/api/query/match_all_filter.rb +11 -0
  35. data/lib/mm_es_search/api/query/match_all_query.rb +19 -0
  36. data/lib/mm_es_search/api/query/nested_filter.rb +22 -0
  37. data/lib/mm_es_search/api/query/nested_query.rb +62 -0
  38. data/lib/mm_es_search/api/query/not_filter.rb +9 -0
  39. data/lib/mm_es_search/api/query/or_filter.rb +9 -0
  40. data/lib/mm_es_search/api/query/prefix_filter.rb +11 -0
  41. data/lib/mm_es_search/api/query/prefix_query.rb +34 -0
  42. data/lib/mm_es_search/api/query/query_filter.rb +28 -0
  43. data/lib/mm_es_search/api/query/query_string_query.rb +37 -0
  44. data/lib/mm_es_search/api/query/range_filter.rb +11 -0
  45. data/lib/mm_es_search/api/query/range_query.rb +57 -0
  46. data/lib/mm_es_search/api/query/scored_filter.rb +29 -0
  47. data/lib/mm_es_search/api/query/single_bool_filter.rb +66 -0
  48. data/lib/mm_es_search/api/query/term_filter.rb +11 -0
  49. data/lib/mm_es_search/api/query/term_query.rb +34 -0
  50. data/lib/mm_es_search/api/query/terms_filter.rb +11 -0
  51. data/lib/mm_es_search/api/query/terms_query.rb +58 -0
  52. data/lib/mm_es_search/api/query/text_query.rb +42 -0
  53. data/lib/mm_es_search/api/query/top_children_query.rb +28 -0
  54. data/lib/mm_es_search/api/sort/root_sort.rb +36 -0
  55. data/lib/mm_es_search/models/abstract_facet_model.rb +23 -0
  56. data/lib/mm_es_search/models/abstract_query_model.rb +21 -0
  57. data/lib/mm_es_search/models/abstract_range_facet_model.rb +365 -0
  58. data/lib/mm_es_search/models/abstract_search_model.OLD +538 -0
  59. data/lib/mm_es_search/models/abstract_search_model.rb +521 -0
  60. data/lib/mm_es_search/models/abstract_sort_model.rb +13 -0
  61. data/lib/mm_es_search/models/abstract_terms_facet_model.rb +87 -0
  62. data/lib/mm_es_search/models/root_sort_model.rb +20 -0
  63. data/lib/mm_es_search/models/virtual_field_sort.rb +52 -0
  64. data/lib/mm_es_search/utils/facet_row_utils.rb +86 -0
  65. data/lib/mm_es_search/utils/search_logger.rb +10 -0
  66. data/lib/mm_es_search/version.rb +3 -0
  67. data/lib/mm_es_search.rb +124 -0
  68. data/mm_es_search.gemspec +24 -0
  69. metadata +132 -0
@@ -0,0 +1,52 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class CustomFiltersScoreQuery < AbstractQuery
6
+
7
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
8
+ many :scored_filters, :class_name => 'MmEsSearch::Api::Query::ScoredFilter'
9
+ key :score_mode, Symbol
10
+
11
+ def to_mongo_query(options = {})
12
+ query = self.query.is_a?(MatchAllQuery) ? nil : self.query
13
+ filters = (scored_filters.map(&:filter) << query).compact
14
+ AndFilter.new(:filters => filters).to_mongo_query(options)
15
+ end
16
+
17
+ def to_es_query
18
+ query_params = {
19
+ :query => query.to_es_query,
20
+ :filters => scored_filters.map(&:to_es_query)
21
+ }
22
+ query_params[:score_mode] = score_mode unless score_mode.nil?
23
+ {:custom_filters_score => query_params}
24
+ end
25
+
26
+ end
27
+
28
+ class ScoredFilter
29
+
30
+ include MongoMapper::EmbeddedDocument
31
+ plugin MmUsesNoId
32
+
33
+ one :filter, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
34
+ key :boost, Float
35
+ key :script, String
36
+
37
+ def to_mongo_query
38
+ filter.to_mongo_query
39
+ end
40
+
41
+ def to_es_query
42
+ filter_params = attributes.except('filter', '_type')
43
+ filter_params[:filter] = filter.to_es_query
44
+ filter_params
45
+ end
46
+
47
+
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,31 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class CustomScoreQuery < AbstractQuery
6
+
7
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
8
+ key :script, String
9
+
10
+ def to_mongo_query(options = {})
11
+
12
+ return query.to_mongo_query(options)
13
+
14
+ end
15
+
16
+ def to_es_query
17
+
18
+ custom_score_params = {
19
+ :query => query.to_es_query,
20
+ :script => script
21
+ }
22
+
23
+ return {:custom_score => custom_score_params}
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class DismaxQuery < AbstractQuery
6
+
7
+ many :queries, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
8
+ key :tie_breaker, Float
9
+ key :boost, Float
10
+
11
+ def to_mongo_query(options = {})
12
+ raise 'Dis Max Query cannot be run as a mongo query'
13
+ end
14
+
15
+ def to_es_query
16
+
17
+ dismax_params = {:queries => queries.map(&:to_es_query)}
18
+ dismax_params.merge!(:tie_breaker => tie_breaker) if tie_breaker?
19
+ dismax_params.merge!(:boost => boost) if boost?
20
+
21
+ return {:dis_max => dismax_params}
22
+
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,30 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class FilteredQuery < AbstractQuery
6
+
7
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
8
+ one :filter, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
9
+
10
+ def to_mongo_query(options = {})
11
+ if query.is_a?(MatchAllQuery) or query.nil?
12
+ filter.to_mongo_query(options)
13
+ else
14
+ AndFilter.new(:filters => [query, filter]).to_mongo_query(options)
15
+ end
16
+ end
17
+
18
+ def to_es_query
19
+ if query.is_a?(MatchAllQuery) or query.nil?
20
+ {:filtered => {:query => MatchAllQuery.new.to_es_query, :filter => filter.to_es_query}}
21
+ else
22
+ {:filtered => {:query => query.to_es_query, :filter => filter.to_es_query}}
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class HasChildFilter < HasChildQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class HasChildQuery < AbstractQuery
6
+
7
+ key :type, Symbol
8
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
9
+ key :scope, String
10
+
11
+ def to_mongo_query(options = {})
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def to_es_query
16
+ params = {:type => type, :query => query.to_es_query}
17
+ params[:_scope] = scope if scope?
18
+ {:has_child => params}
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class HasParentFilter < HasParentQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,25 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class HasParentQuery < AbstractQuery
6
+
7
+ key :parent_type, Symbol
8
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
9
+ key :scope, String
10
+
11
+ def to_mongo_query(options = {})
12
+ raise NotImplementedError
13
+ end
14
+
15
+ def to_es_query
16
+ params = {:parent_type => parent_type, :query => query.to_es_query}
17
+ params[:_scope] = scope if scope?
18
+ {:has_parent => params}
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class MatchAllFilter < MatchAllQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,19 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class MatchAllQuery < AbstractQuery
6
+
7
+ def to_mongo_query(options = {})
8
+ return {}
9
+ end
10
+
11
+ def to_es_query
12
+ return {:match_all => {}}
13
+ end
14
+
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class NestedFilter < NestedQuery
6
+
7
+ plugin AbstractFilter
8
+ private
9
+
10
+ def es_api_keyword
11
+ :filter
12
+ end
13
+
14
+ def anded_query(query_array)
15
+ AndFilter.new(:filters => query_array)
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,62 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class NestedQuery < AbstractQuery
6
+
7
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
8
+ key :path, String
9
+ key :score_mode, String
10
+ key :_scope, String
11
+ key :array_index_name, String
12
+
13
+ def to_mongo_query(options = {})
14
+
15
+ mod_path, array_index = path_and_index
16
+ if array_index.nil?
17
+ #NOTE: we assume here that earlier terms in a dot-joined path has been used in an enclosing nested query
18
+ {path.split('.').last => {'$elemMatch' => query.to_mongo_query(options)}}
19
+ else
20
+ query.to_mongo_query(options) #don't need elemMatch as index means we're addressing one document only
21
+ end
22
+
23
+ end
24
+
25
+ def to_es_query
26
+
27
+ mod_path, array_index = path_and_index
28
+ mod_query = if array_index.nil?
29
+ query
30
+ else
31
+ query_array = [
32
+ query,
33
+ TermQuery.new(:path => mod_path, :field => array_index_name || '_array_index', :value => array_index)]
34
+ anded_query(query_array)
35
+ end
36
+
37
+ nested_params = {
38
+ es_api_keyword => mod_query.to_es_query,
39
+ :path => mod_path
40
+ }
41
+ nested_params.merge!({:score_mode => score_mode}) unless score_mode.nil?
42
+ nested_params.merge!({:_scope => _scope}) unless _scope.nil?
43
+
44
+ return {:nested => nested_params}
45
+
46
+ end
47
+
48
+ private
49
+
50
+ def es_api_keyword
51
+ :query
52
+ end
53
+
54
+ def anded_query(query_array)
55
+ BoolQuery.new(:musts => query_array)
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,9 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class NotFilter < SingleBoolFilter; end
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class OrFilter < SingleBoolFilter; end
6
+
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class PrefixFilter < PrefixQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class PrefixQuery < AbstractQuery
6
+
7
+ key :field, String
8
+ key :path, String
9
+
10
+ key :value, String
11
+ key :boost, Float
12
+
13
+ def to_mongo_query(options = {})
14
+ prefix_regex = /^#{value}/
15
+ if options[:negated]
16
+ {mongo_abs_field => {'$ne' => prefix_regex}}
17
+ else
18
+ {mongo_abs_field => prefix_regex}
19
+ end
20
+ end
21
+
22
+ def to_es_query
23
+ if boost
24
+ {:prefix => {es_abs_field => {:value => value, :boost => boost}}}
25
+ else
26
+ {:prefix => {es_abs_field => value}}
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class QueryFilter < AbstractQuery
6
+ plugin AbstractFilter
7
+
8
+ one :query, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
9
+ key :cache, Boolean
10
+
11
+ def to_mongo_query
12
+ query.to_mongo_query
13
+ end
14
+
15
+ def to_es_query
16
+ query_params = {
17
+ :query => query.to_es_query
18
+ }
19
+ query_params[:_cache] = cache unless cache.nil?
20
+ {:fquery => query_params}
21
+ end
22
+
23
+
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,37 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class QueryStringQuery < AbstractQuery
6
+
7
+ key :query, String
8
+ key :default_field, String
9
+ key :boost, Float
10
+ key :default_operator, String
11
+ key :analyzer, String
12
+ key :allow_leading_wildcard, Boolean
13
+ key :lowercase_expanded_terms, Boolean
14
+ key :enable_position_increments, Boolean
15
+ key :fuzzy_prefix_length, Integer
16
+ key :fuzzy_min_sim, Float
17
+ key :phrase_slop, Integer
18
+ key :analyze_wildcard, Boolean
19
+ key :auto_generate_phrase_queries, Boolean
20
+
21
+ def to_mongo_query(options = {})
22
+
23
+ raise "QueryStringQuery doesn't support mongo execution"
24
+
25
+ end
26
+
27
+ def to_es_query
28
+
29
+ return {:query_string => self.attributes.except("_type")}
30
+
31
+ end
32
+
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class RangeFilter < RangeQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class RangeQuery < AbstractQuery
6
+
7
+ key :field, String
8
+ key :path, String
9
+
10
+ key :from
11
+ key :to
12
+ key :include_lower, :default => true
13
+ key :include_upper, :default => true
14
+ key :boost, Float
15
+
16
+ def to_mongo_query(options = {})
17
+
18
+ range_params = {}
19
+
20
+ if from
21
+ cmd = include_lower ? '$gte' : '$gt'
22
+ range_params.merge!({cmd => from})
23
+ end
24
+
25
+ if to
26
+ cmd = include_upper ? '$lte' : '$lt'
27
+ range_params.merge!({cmd => to})
28
+ end
29
+
30
+ if options[:negated]
31
+ return {mongo_abs_field => {"$not" => range_params}}
32
+ else
33
+ return {mongo_abs_field => range_params}
34
+ end
35
+
36
+ end
37
+
38
+ def to_es_query
39
+
40
+ raise "must have either :from or :to" if from.nil? and to.nil?
41
+
42
+ range_params = {}
43
+ range_params.merge!({:from => from}) unless from.nil?
44
+ range_params.merge!({:to => to}) unless to.nil?
45
+ range_params.merge!({:include_lower => include_lower}) unless (from.nil? or include_lower == true)
46
+ range_params.merge!({:include_upper => include_upper}) unless (to.nil? or include_upper == true)
47
+ range_params.merge!({:boost => boost}) unless boost.nil?
48
+
49
+ return {:range => {es_abs_field => range_params}}
50
+
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,29 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class ScoredFilter
6
+
7
+ include MongoMapper::EmbeddedDocument
8
+ plugin MmUsesNoId
9
+
10
+ one :filter, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
11
+ key :boost, Float
12
+ key :script, String
13
+
14
+ def to_mongo_query
15
+ filter.to_mongo_query
16
+ end
17
+
18
+ def to_es_query
19
+ filter_params = attributes.except('filter', '_type')
20
+ filter_params[:filter] = filter.to_es_query
21
+ filter_params
22
+ end
23
+
24
+
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,66 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class SingleBoolFilter < AbstractQuery
6
+
7
+ plugin AbstractFilter
8
+
9
+ many :filters, :class_name => 'MmEsSearch::Api::Query::AbstractQuery'
10
+ key :_cache, Boolean
11
+
12
+ def operator_name
13
+ self.class.to_s[0..-7].split('::').last.downcase #strip off "Filter" and downcase e.g. AndFilter => filter
14
+ end
15
+
16
+ def optimize_filters
17
+ opt_filters = []
18
+ filters.each do |child_filter|
19
+ if child_filter.is_a?(self.class)
20
+ opt_filters += child_filter.filters
21
+ else
22
+ opt_filters << child_filter
23
+ end
24
+ end
25
+ opt_filters
26
+ end
27
+
28
+ def to_mongo_query(options = {})
29
+ case self
30
+ when NotFilter
31
+ negated_options = options.merge({:negated => !options[:negated]})
32
+ return AndFilter.new(:filters => filters).to_mongo_query(negated_options)
33
+ else
34
+ opt_filters = optimize_filters
35
+ filter_array = opt_filters.map {|filter| filter.to_mongo_query(options)}
36
+ if filter_array.length == 1
37
+ return filter_array.first
38
+ else
39
+ return {"$#{operator_name}" => filter_array}
40
+ end
41
+ end
42
+ end
43
+
44
+ def to_es_query
45
+ opt_filters = optimize_filters
46
+ filter_array = opt_filters.map {|query| query.to_es_query}
47
+ params = {}
48
+ case self
49
+ when NotFilter
50
+ if filter_array.length == 1
51
+ return {operator_name => {:filter => filter_array.first}}
52
+ else
53
+ return {operator_name => {:filter => {:or => filter_array}}}
54
+ end
55
+ else
56
+ params = {operator_name => filter_array}
57
+ end
58
+ params.merge!({"_cache" => _cache}) unless _cache.nil?
59
+ return params
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,11 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class TermFilter < TermQuery
6
+ plugin AbstractFilter
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ module MmEsSearch
2
+ module Api
3
+ module Query
4
+
5
+ class TermQuery < AbstractQuery
6
+
7
+ key :field, String
8
+ key :path, String
9
+
10
+ key :value #string or number
11
+ key :boost, Float
12
+
13
+ def to_mongo_query(options = {})
14
+
15
+ if options[:negated]
16
+ {mongo_abs_field => {'$ne' => value}}
17
+ else
18
+ {mongo_abs_field => value}
19
+ end
20
+ end
21
+
22
+ def to_es_query
23
+ if boost
24
+ {:term => {es_abs_field => {:value => value, :boost => boost}}}
25
+ else
26
+ {:term => {es_abs_field => value}}
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ end
33
+ end
34
+ end