model_set 1.0.0 → 1.1.0
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.
- data/.gitignore +3 -0
- data/.rbenv-gemsets +1 -0
- data/.rbenv-version +1 -0
- data/Gemfile +3 -0
- data/Rakefile +2 -39
- data/VERSION +1 -1
- data/lib/model_set/conditioned.rb +14 -15
- data/lib/model_set/conditions.rb +26 -33
- data/lib/model_set/query.rb +16 -12
- data/lib/model_set/solr_query.rb +40 -30
- data/lib/model_set/sphinx_query.rb +89 -43
- data/lib/model_set/sql_base_query.rb +27 -15
- data/lib/model_set/sql_query.rb +8 -10
- data/lib/model_set.rb +39 -15
- data/model_set.gemspec +24 -136
- data/test/model_set_test.rb +18 -0
- data/test/test_helper.rb +1 -6
- data/vendor/sphinx_client/lib/sphinx/client.rb +68 -18
- data/vendor/sphinx_client/lib/sphinx/response.rb +68 -68
- data/vendor/sphinx_client/spec/client_spec.rb +4 -4
- data/vendor/sphinx_client/spec/fixtures/keywords.php +7 -7
- data/vendor/sphinx_client/spec/fixtures/sphinxapi.php +5 -3
- data/vendor/sphinx_client/spec/sphinx/sphinx-id64.conf +1 -1
- data/vendor/sphinx_client/spec/sphinx/sphinx.conf +1 -1
- data/vendor/sphinx_client/test.rb +27 -0
- metadata +131 -24
data/.gitignore
ADDED
data/.rbenv-gemsets
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
model_set
|
data/.rbenv-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ree-1.8.7-2012.02
|
data/Gemfile
ADDED
data/Rakefile
CHANGED
@@ -1,47 +1,10 @@
|
|
1
|
-
require 'rake'
|
2
1
|
require 'rake/testtask'
|
3
|
-
require '
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'jeweler'
|
7
|
-
Jeweler::Tasks.new do |s|
|
8
|
-
s.name = "model_set"
|
9
|
-
s.summary = %Q{Easy manipulation of sets of ActiveRecord models}
|
10
|
-
s.email = "code@justinbalthrop.com"
|
11
|
-
s.homepage = "http://github.com/ninjudd/model_set"
|
12
|
-
s.description = "Easy manipulation of sets of ActiveRecord models"
|
13
|
-
s.authors = ["Justin Balthrop"]
|
14
|
-
s.add_dependency('ordered_set', '>= 1.0.1')
|
15
|
-
s.add_dependency('deep_clonable', '>= 1.1.0')
|
16
|
-
s.add_dependency('activerecord', '>= 2.0.0')
|
17
|
-
end
|
18
|
-
Jeweler::GemcutterTasks.new
|
19
|
-
rescue LoadError
|
20
|
-
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
21
|
-
end
|
2
|
+
require 'bundler/gem_tasks'
|
22
3
|
|
23
4
|
Rake::TestTask.new do |t|
|
24
|
-
t.libs
|
5
|
+
t.libs = ['lib']
|
25
6
|
t.pattern = 'test/**/*_test.rb'
|
26
7
|
t.verbose = false
|
27
8
|
end
|
28
9
|
|
29
|
-
Rake::RDocTask.new do |rdoc|
|
30
|
-
rdoc.rdoc_dir = 'rdoc'
|
31
|
-
rdoc.title = 'model_set'
|
32
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
33
|
-
rdoc.rdoc_files.include('README*')
|
34
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
35
|
-
end
|
36
|
-
|
37
|
-
begin
|
38
|
-
require 'rcov/rcovtask'
|
39
|
-
Rcov::RcovTask.new do |t|
|
40
|
-
t.libs << 'test'
|
41
|
-
t.test_files = FileList['test/**/*_test.rb']
|
42
|
-
t.verbose = true
|
43
|
-
end
|
44
|
-
rescue LoadError
|
45
|
-
end
|
46
|
-
|
47
10
|
task :default => :test
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.0
|
@@ -2,28 +2,27 @@ class ModelSet
|
|
2
2
|
module Conditioned
|
3
3
|
# Shared methods for dealing with conditions.
|
4
4
|
attr_accessor :conditions
|
5
|
-
|
6
|
-
def add_conditions!(*conditions)
|
7
|
-
operator = conditions.shift if conditions.first.kind_of?(Symbol)
|
8
|
-
operator ||= :and
|
9
5
|
|
10
|
-
|
11
|
-
conditions.
|
12
|
-
condition.kind_of?(Conditions) ? condition : Conditions.new( sanitize_condition(condition) )
|
13
|
-
end
|
6
|
+
def add_conditions!(*conditions)
|
7
|
+
new_conditions = conditions.first.kind_of?(Symbol) ? [conditions.shift] : []
|
14
8
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
9
|
+
conditions.each do |condition|
|
10
|
+
if condition.kind_of?(Conditions)
|
11
|
+
new_conditions << condition
|
12
|
+
else
|
13
|
+
new_conditions.concat([*transform_condition(condition)])
|
14
|
+
end
|
19
15
|
end
|
16
|
+
return self if new_conditions.empty?
|
20
17
|
|
21
|
-
conditions
|
22
|
-
@conditions = Conditions.new(operator, *conditions)
|
23
|
-
|
18
|
+
@conditions = to_conditions(*new_conditions) << @conditions
|
24
19
|
clear_cache!
|
25
20
|
end
|
26
21
|
|
22
|
+
def to_conditions(*conditions)
|
23
|
+
Conditions.new(conditions, condition_ops)
|
24
|
+
end
|
25
|
+
|
27
26
|
def invert!
|
28
27
|
raise 'cannot invert without conditions' if @conditions.nil?
|
29
28
|
@conditions = ~@conditions
|
data/lib/model_set/conditions.rb
CHANGED
@@ -4,40 +4,27 @@ class ModelSet
|
|
4
4
|
|
5
5
|
attr_reader :operator, :conditions
|
6
6
|
|
7
|
-
def self.new(*args)
|
8
|
-
if args.size == 1 and args.first.kind_of?(self)
|
9
|
-
# Just clone if the only argument is a Conditions object.
|
10
|
-
args.first.clone
|
11
|
-
elsif args.size == 2 and [:and, :or].include?(args.first)
|
12
|
-
# The operator is not necessary if there is only one subcondition.
|
13
|
-
new(args.last)
|
14
|
-
else
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
7
|
def new(*args)
|
20
8
|
self.class.new(*args)
|
21
9
|
end
|
22
10
|
|
23
|
-
def initialize(
|
24
|
-
|
25
|
-
|
26
|
-
@
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
if operator == :not
|
32
|
-
raise "unary operator :not cannot have multiple conditions" if args.size > 1
|
33
|
-
@conditions = [self.class.new(args.first)]
|
11
|
+
def initialize(conditions, ops)
|
12
|
+
@ops = ops
|
13
|
+
if conditions.kind_of?(Array)
|
14
|
+
@operator = conditions.first.kind_of?(Symbol) ? conditions.shift : :and
|
15
|
+
if @operator == :not
|
16
|
+
# In this case, :not actually means :and :not.
|
17
|
+
@conditions = ~Conditions.new([:and, conditions], @ops)
|
34
18
|
else
|
19
|
+
raise "invalid operator :#{operator}" unless [:and, :or].include?(@operator)
|
35
20
|
# Compact the conditions if possible.
|
36
21
|
@conditions = []
|
37
|
-
|
22
|
+
conditions.each do |clause|
|
38
23
|
self << clause
|
39
24
|
end
|
40
25
|
end
|
26
|
+
else
|
27
|
+
@conditions = [conditions]
|
41
28
|
end
|
42
29
|
end
|
43
30
|
|
@@ -46,15 +33,17 @@ class ModelSet
|
|
46
33
|
end
|
47
34
|
|
48
35
|
def <<(clause)
|
36
|
+
return self unless clause
|
49
37
|
raise 'cannot append conditions to a terminal' if terminal?
|
50
|
-
|
51
|
-
clause =
|
38
|
+
|
39
|
+
clause = new(clause, @ops) unless clause.kind_of?(Conditions)
|
52
40
|
if clause.operator == operator
|
53
41
|
@conditions.concat(clause.conditions)
|
54
42
|
else
|
55
43
|
@conditions << clause
|
56
44
|
end
|
57
45
|
@conditions.uniq!
|
46
|
+
self
|
58
47
|
end
|
59
48
|
|
60
49
|
def ~
|
@@ -73,20 +62,24 @@ class ModelSet
|
|
73
62
|
new(:and, self, other)
|
74
63
|
end
|
75
64
|
|
65
|
+
def op(type)
|
66
|
+
@ops[type]
|
67
|
+
end
|
68
|
+
|
76
69
|
def to_s
|
77
|
-
return conditions.first if terminal?
|
70
|
+
return conditions.first.to_s if terminal? or conditions.empty?
|
78
71
|
|
79
72
|
condition_strings = conditions.collect do |condition|
|
80
73
|
condition.operator == :not ? condition.to_s : "(#{condition.to_s})"
|
81
74
|
end.sort_by {|s| s.size}
|
82
75
|
|
83
76
|
case operator
|
84
|
-
when :not
|
85
|
-
"
|
86
|
-
when :and
|
87
|
-
"#{condition_strings.join(
|
88
|
-
when :or
|
89
|
-
"#{condition_strings.join(
|
77
|
+
when :not then
|
78
|
+
"#{op(:not)} #{condition_strings.first}"
|
79
|
+
when :and then
|
80
|
+
"#{condition_strings.join(op(:and))}"
|
81
|
+
when :or then
|
82
|
+
"#{condition_strings.join(op(:or))}"
|
90
83
|
end
|
91
84
|
end
|
92
85
|
|
data/lib/model_set/query.rb
CHANGED
@@ -37,27 +37,28 @@ class ModelSet
|
|
37
37
|
@page = nil if offset
|
38
38
|
clear_limited_cache!
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
def unlimited!
|
42
42
|
@limit = nil
|
43
43
|
@offset = nil
|
44
44
|
@page = nil
|
45
45
|
clear_limited_cache!
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
def clear_limited_cache!
|
49
49
|
@ids = nil
|
50
50
|
@size = nil
|
51
51
|
self
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
def clear_cache!
|
55
55
|
@count = nil
|
56
56
|
clear_limited_cache!
|
57
57
|
end
|
58
58
|
|
59
|
-
attr_reader :set_class
|
60
|
-
delegate :id_field,
|
59
|
+
attr_reader :set_class, :limit, :sort_order
|
60
|
+
delegate :id_field, :to => :set_class
|
61
|
+
delegate :id_field_with_prefix, :to => :set_class
|
61
62
|
|
62
63
|
def model_class
|
63
64
|
set_class.query_model_class
|
@@ -71,12 +72,6 @@ class ModelSet
|
|
71
72
|
model_class.table_name
|
72
73
|
end
|
73
74
|
|
74
|
-
def id_field_with_prefix
|
75
|
-
"#{table_name}.#{id_field}"
|
76
|
-
end
|
77
|
-
|
78
|
-
attr_reader :limit, :sort_order
|
79
|
-
|
80
75
|
def offset
|
81
76
|
if limit
|
82
77
|
@offset ||= @page ? (@page - 1) * limit : 0
|
@@ -97,7 +92,7 @@ class ModelSet
|
|
97
92
|
proc = self.class.before_query
|
98
93
|
proc.bind(self).call(*args) if proc
|
99
94
|
end
|
100
|
-
|
95
|
+
|
101
96
|
def self.before_query(&block)
|
102
97
|
if block
|
103
98
|
@before_query = block
|
@@ -132,5 +127,14 @@ class ModelSet
|
|
132
127
|
end
|
133
128
|
end
|
134
129
|
|
130
|
+
def condition_ops
|
131
|
+
{ :not => 'NOT ',
|
132
|
+
:and => ' AND ',
|
133
|
+
:or => ' OR ' }
|
134
|
+
end
|
135
|
+
|
136
|
+
def transform_condition(condition)
|
137
|
+
[condition]
|
138
|
+
end
|
135
139
|
end
|
136
140
|
end
|
data/lib/model_set/solr_query.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
|
-
require '
|
1
|
+
require 'rsolr'
|
2
|
+
require 'json'
|
2
3
|
|
3
4
|
class ModelSet
|
4
5
|
class SolrQuery < Query
|
5
|
-
attr_reader :response
|
6
6
|
include Conditioned
|
7
7
|
|
8
8
|
MAX_SOLR_RESULTS = 1000
|
9
9
|
|
10
|
+
class << self
|
11
|
+
attr_accessor :host
|
12
|
+
end
|
13
|
+
attr_reader :response
|
14
|
+
|
10
15
|
def anchor!(query)
|
11
16
|
add_conditions!( ids_clause(query.ids) )
|
12
|
-
end
|
17
|
+
end
|
13
18
|
|
14
19
|
def size
|
15
20
|
fetch_results if @size.nil?
|
@@ -26,41 +31,50 @@ class ModelSet
|
|
26
31
|
@ids
|
27
32
|
end
|
28
33
|
|
29
|
-
def
|
30
|
-
@
|
34
|
+
def use_core!(core)
|
35
|
+
@core = core
|
31
36
|
end
|
32
37
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
query = "#{conditions.to_s}"
|
37
|
-
solr_params = {:highlighting => {}}
|
38
|
+
def solr_params!(opts)
|
39
|
+
@opts = opts
|
40
|
+
end
|
38
41
|
|
39
|
-
|
40
|
-
|
42
|
+
def id_field
|
43
|
+
if set_class.respond_to?(:solr_id_field)
|
44
|
+
set_class.solr_id_field
|
45
|
+
else
|
46
|
+
'id'
|
41
47
|
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
42
51
|
|
52
|
+
def fetch_results
|
53
|
+
params = @opts || {}
|
54
|
+
params[:q] = "#{conditions.to_s}"
|
55
|
+
params[:fl] ||= [id_field]
|
56
|
+
params[:fl] = params[:fl].join(",")
|
57
|
+
params[:wt] = :json
|
43
58
|
if limit
|
44
|
-
|
45
|
-
|
59
|
+
params[:rows] = limit
|
60
|
+
params[:start] = offset
|
46
61
|
else
|
47
|
-
|
62
|
+
params[:rows] = MAX_SOLR_RESULTS
|
48
63
|
end
|
49
64
|
|
50
|
-
before_query(
|
51
|
-
begin
|
52
|
-
|
53
|
-
if @
|
54
|
-
|
55
|
-
|
56
|
-
@response = Solr::Connection.new(solr_uri).search(query, solr_params)
|
65
|
+
before_query(params)
|
66
|
+
begin
|
67
|
+
url = "http://" + self.class.host
|
68
|
+
url += "/" + @core if @core
|
69
|
+
search = RSolr.connect(:url => url)
|
70
|
+
@response = JSON.parse(search.get('select', :params => params))
|
57
71
|
rescue Exception => e
|
58
|
-
on_exception(e,
|
72
|
+
on_exception(e, params)
|
59
73
|
end
|
60
|
-
after_query(
|
74
|
+
after_query(params)
|
61
75
|
|
62
|
-
@count =
|
63
|
-
@ids =
|
76
|
+
@count = response['response']['numFound']
|
77
|
+
@ids = response['response']['docs'].collect {|doc| set_class.as_id(doc[id_field])}.to_ordered_set
|
64
78
|
@size = @ids.size
|
65
79
|
end
|
66
80
|
|
@@ -69,9 +83,5 @@ class ModelSet
|
|
69
83
|
field ||= 'pk_i'
|
70
84
|
"#{field}:(#{ids.join(' OR ')})"
|
71
85
|
end
|
72
|
-
|
73
|
-
def sanitize_condition(condition)
|
74
|
-
condition
|
75
|
-
end
|
76
86
|
end
|
77
87
|
end
|
@@ -1,20 +1,17 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../../vendor/sphinx_client/lib/sphinx'
|
2
|
-
|
3
|
-
require 'system_timer'
|
4
|
-
rescue LoadError => e
|
5
|
-
module SystemTimer
|
6
|
-
def self.timeout(time, &block)
|
7
|
-
Timeout.timeout(time, &block)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
2
|
+
require 'system_timer'
|
11
3
|
|
12
4
|
class ModelSet
|
13
5
|
class SphinxQuery < Query
|
14
|
-
|
15
|
-
MAX_QUERY_TIME = 5
|
6
|
+
include Conditioned
|
16
7
|
|
17
|
-
|
8
|
+
MAX_RESULTS = 1000
|
9
|
+
MAX_QUERY_TIME = 5
|
10
|
+
|
11
|
+
class << self
|
12
|
+
attr_accessor :host, :port
|
13
|
+
end
|
14
|
+
attr_reader :filters, :response
|
18
15
|
|
19
16
|
def max_query_time
|
20
17
|
@max_query_time || MAX_QUERY_TIME
|
@@ -24,6 +21,14 @@ class ModelSet
|
|
24
21
|
@max_query_time = seconds
|
25
22
|
end
|
26
23
|
|
24
|
+
def max_results
|
25
|
+
@max_results || MAX_RESULTS
|
26
|
+
end
|
27
|
+
|
28
|
+
def max_results!(max)
|
29
|
+
@max_results = max
|
30
|
+
end
|
31
|
+
|
27
32
|
def anchor!(query)
|
28
33
|
add_filters!( id_field => query.ids.to_a )
|
29
34
|
end
|
@@ -43,28 +48,20 @@ class ModelSet
|
|
43
48
|
@geo = opts
|
44
49
|
end
|
45
50
|
|
46
|
-
def add_conditions!(conditions)
|
47
|
-
if conditions.kind_of?(Hash)
|
48
|
-
conditions.each do |field, value|
|
49
|
-
next if value.nil?
|
50
|
-
field = field.join(',') if field.kind_of?(Array)
|
51
|
-
value = "(#{value.join('|')})" if value.kind_of?(Array)
|
52
|
-
add_conditions!("@(#{field}) #{value}")
|
53
|
-
end
|
54
|
-
else
|
55
|
-
@conditions ||= []
|
56
|
-
@conditions << conditions
|
57
|
-
@conditions.uniq!
|
58
|
-
clear_cache!
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
51
|
def index
|
63
52
|
@index ||= '*'
|
64
53
|
end
|
65
54
|
|
66
|
-
def use_index!(index)
|
67
|
-
|
55
|
+
def use_index!(index, opts = {})
|
56
|
+
if opts[:delta]
|
57
|
+
@index = "#{index} #{index}_delta"
|
58
|
+
else
|
59
|
+
@index = index
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def select_fields!(*fields)
|
64
|
+
@select = fields.flatten
|
68
65
|
end
|
69
66
|
|
70
67
|
SORT_MODES = {
|
@@ -72,7 +69,7 @@ class ModelSet
|
|
72
69
|
:descending => Sphinx::Client::SPH_SORT_ATTR_DESC,
|
73
70
|
:ascending => Sphinx::Client::SPH_SORT_ATTR_ASC,
|
74
71
|
:time => Sphinx::Client::SPH_SORT_TIME_SEGMENTS,
|
75
|
-
:
|
72
|
+
:extended => Sphinx::Client::SPH_SORT_EXTENDED,
|
76
73
|
:expression => Sphinx::Client::SPH_SORT_EXPR,
|
77
74
|
}
|
78
75
|
|
@@ -86,6 +83,27 @@ class ModelSet
|
|
86
83
|
clear_cache!
|
87
84
|
end
|
88
85
|
|
86
|
+
RANKING_MODES = {
|
87
|
+
:proximity_bm25 => Sphinx::Client::SPH_RANK_PROXIMITY_BM25,
|
88
|
+
:bm25 => Sphinx::Client::SPH_RANK_BM25,
|
89
|
+
:none => Sphinx::Client::SPH_RANK_NONE,
|
90
|
+
:word_count => Sphinx::Client::SPH_RANK_WORDCOUNT,
|
91
|
+
:proximity => Sphinx::Client::SPH_RANK_PROXIMITY,
|
92
|
+
:fieldmask => Sphinx::Client::SPH_RANK_FIELDMASK,
|
93
|
+
:sph04 => Sphinx::Client::SPH_RANK_SPH04,
|
94
|
+
:total => Sphinx::Client::SPH_RANK_TOTAL,
|
95
|
+
}
|
96
|
+
|
97
|
+
def rank_using!(mode_or_expr)
|
98
|
+
if mode_or_expr.nil?
|
99
|
+
@ranking = nil
|
100
|
+
elsif mode = RANKING_MODES[mode_or_expr]
|
101
|
+
@ranking = [mode]
|
102
|
+
else
|
103
|
+
@ranking = [Sphinx::Client::SPH_RANK_EXPR, mode_or_expr]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
89
107
|
def size
|
90
108
|
fetch_results if @size.nil?
|
91
109
|
@size
|
@@ -96,11 +114,23 @@ class ModelSet
|
|
96
114
|
@count
|
97
115
|
end
|
98
116
|
|
117
|
+
def total_count
|
118
|
+
response['total_found']
|
119
|
+
end
|
120
|
+
|
99
121
|
def ids
|
100
122
|
fetch_results if @ids.nil?
|
101
123
|
@ids
|
102
124
|
end
|
103
125
|
|
126
|
+
def id_field
|
127
|
+
if set_class.respond_to?(:sphinx_id_field)
|
128
|
+
set_class.sphinx_id_field
|
129
|
+
else
|
130
|
+
'id'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
104
134
|
class SphinxError < StandardError
|
105
135
|
attr_accessor :opts
|
106
136
|
def message
|
@@ -111,28 +141,30 @@ class ModelSet
|
|
111
141
|
private
|
112
142
|
|
113
143
|
def fetch_results
|
114
|
-
if
|
144
|
+
if conditions.nil? or @empty
|
115
145
|
@count = 0
|
116
146
|
@size = 0
|
117
147
|
@ids = []
|
118
148
|
else
|
119
149
|
opts = {
|
120
150
|
:filters => @filters,
|
121
|
-
:query =>
|
151
|
+
:query => conditions.to_s,
|
122
152
|
}
|
123
153
|
before_query(opts)
|
124
154
|
|
125
155
|
search = Sphinx::Client.new
|
126
156
|
search.SetMaxQueryTime(max_query_time * 1000)
|
127
|
-
search.SetServer(self.class.
|
157
|
+
search.SetServer(self.class.host, self.class.port)
|
158
|
+
search.SetSelect((@select || [id_field]).join(','))
|
128
159
|
search.SetMatchMode(Sphinx::Client::SPH_MATCH_EXTENDED2)
|
129
160
|
if limit
|
130
|
-
search.SetLimits(offset, limit,
|
161
|
+
search.SetLimits(offset, limit, max_results)
|
131
162
|
else
|
132
|
-
search.SetLimits(0,
|
163
|
+
search.SetLimits(0, max_results, max_results)
|
133
164
|
end
|
134
165
|
|
135
166
|
search.SetSortMode(*@sort_order) if @sort_order
|
167
|
+
search.SetRankingMode(*@ranking) if @ranking
|
136
168
|
search.SetFilter('class_id', model_class.class_id) if model_class.respond_to?(:class_id)
|
137
169
|
|
138
170
|
if @geo
|
@@ -161,7 +193,7 @@ class ModelSet
|
|
161
193
|
end
|
162
194
|
|
163
195
|
begin
|
164
|
-
response = SystemTimer.timeout(max_query_time) do
|
196
|
+
@response = SystemTimer.timeout(max_query_time) do
|
165
197
|
search.Query(opts[:query], index)
|
166
198
|
end
|
167
199
|
unless response
|
@@ -175,8 +207,8 @@ class ModelSet
|
|
175
207
|
on_exception(e)
|
176
208
|
end
|
177
209
|
|
178
|
-
@count = response['total_found']
|
179
|
-
@ids = response['matches'].collect {|
|
210
|
+
@count = [response['total_found'], max_results].min
|
211
|
+
@ids = response['matches'].collect {|match| set_class.as_id(match[id_field])}.to_ordered_set
|
180
212
|
@size = @ids.size
|
181
213
|
|
182
214
|
after_query(opts)
|
@@ -195,12 +227,26 @@ class ModelSet
|
|
195
227
|
end
|
196
228
|
end
|
197
229
|
|
198
|
-
|
199
|
-
|
230
|
+
def condition_ops
|
231
|
+
{ :not => '-',
|
232
|
+
:and => ' ',
|
233
|
+
:or => '|' }
|
200
234
|
end
|
201
235
|
|
202
|
-
def
|
203
|
-
|
236
|
+
def transform_condition(condition)
|
237
|
+
if condition.kind_of?(Hash)
|
238
|
+
condition.collect do |field, value|
|
239
|
+
next if value.nil?
|
240
|
+
field = field.join(',') if field.kind_of?(Array)
|
241
|
+
if value.kind_of?(Array)
|
242
|
+
value = [:or, *value] unless value.first.kind_of?(Symbol)
|
243
|
+
value = to_conditions(*value).to_s
|
244
|
+
end
|
245
|
+
"@(#{field}) #{value}"
|
246
|
+
end.compact
|
247
|
+
else
|
248
|
+
condition
|
249
|
+
end
|
204
250
|
end
|
205
251
|
end
|
206
252
|
end
|