mm_es_search 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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