tire 0.3.5 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -181,6 +181,18 @@ module Tire
181
181
  logged(error, '_close', curl)
182
182
  end
183
183
 
184
+ def analyze(text, options={})
185
+ options = {:pretty => true}.update(options)
186
+ params = options.to_param
187
+ @response = Configuration.client.get "#{Configuration.url}/#{@name}/_analyze?#{params}", text
188
+ @response.success? ? MultiJson.decode(@response.body) : false
189
+ rescue Exception => error
190
+ raise
191
+ ensure
192
+ curl = %Q|curl -X GET "#{Configuration.url}/#{@name}/_analyze?#{params}" -d '#{text}'|
193
+ logged(error, '_analyze', curl)
194
+ end
195
+
184
196
  def register_percolator_query(name, options={}, &block)
185
197
  options[:query] = Search::Query.new(&block).to_hash if block_given?
186
198
 
@@ -68,15 +68,14 @@ module Tire
68
68
  # for more information.
69
69
  #
70
70
  def indexes(name, options = {}, &block)
71
- options[:type] ||= 'string'
72
-
73
71
  if block_given?
74
- mapping[name] ||= { :type => 'object', :properties => {} }
72
+ mapping[name] ||= { :type => 'object', :properties => {} }.update(options)
75
73
  @_nested_mapping = name
76
74
  nested = yield
77
75
  @_nested_mapping = nil
78
76
  self
79
77
  else
78
+ options[:type] ||= 'string'
80
79
  if @_nested_mapping
81
80
  mapping[@_nested_mapping][:properties][name] = options
82
81
  else
@@ -13,9 +13,9 @@ module Tire
13
13
  @attributes = {}
14
14
  args.each_pair do |key, value|
15
15
  if value.is_a?(Array)
16
- @attributes[key.to_sym] = value.map { |item| @attributes[key.to_sym] = item.is_a?(Hash) ? self.class.new(item.to_hash) : item }
16
+ @attributes[key.to_sym] = value.map { |item| @attributes[key.to_sym] = item.is_a?(Hash) ? Item.new(item.to_hash) : item }
17
17
  else
18
- @attributes[key.to_sym] = value.is_a?(Hash) ? self.class.new(value.to_hash) : value
18
+ @attributes[key.to_sym] = value.is_a?(Hash) ? Item.new(value.to_hash) : value
19
19
  end
20
20
  end
21
21
  end
@@ -59,6 +59,8 @@ module Tire
59
59
  #
60
60
  def class
61
61
  defined?(::Rails) && @attributes[:_type] ? @attributes[:_type].camelize.constantize : super
62
+ rescue NameError
63
+ super
62
64
  end
63
65
 
64
66
  def inspect
@@ -89,7 +89,8 @@ module Tire
89
89
  request.update( { :query => @query.to_hash } ) if @query
90
90
  request.update( { :sort => @sort.to_ary } ) if @sort
91
91
  request.update( { :facets => @facets.to_hash } ) if @facets
92
- @filters.each { |filter| request.update( { :filter => filter.to_hash } ) } if @filters
92
+ request.update( { :filter => @filters.first.to_hash } ) if @filters && @filters.size == 1
93
+ request.update( { :filter => { :and => @filters.map { |filter| filter.to_hash } } } ) if @filters && @filters.size > 1
93
94
  request.update( { :highlight => @highlight.to_hash } ) if @highlight
94
95
  request.update( { :size => @size } ) if @size
95
96
  request.update( { :from => @from } ) if @from
@@ -55,7 +55,7 @@ namespace :tire do
55
55
  mapping = defined?(Yajl) ? Yajl::Encoder.encode(klass.tire.mapping_to_hash, :pretty => true) :
56
56
  MultiJson.encode(klass.tire.mapping_to_hash)
57
57
  puts "[IMPORT] Creating index '#{index.name}' with mapping:", mapping
58
- index.create :mappings => klass.tire.mapping_to_hash
58
+ index.create :mappings => klass.tire.mapping_to_hash, :settings => klass.tire.settings
59
59
  end
60
60
 
61
61
  STDOUT.sync = true
@@ -1,10 +1,12 @@
1
1
  module Tire
2
- VERSION = "0.3.5"
2
+ VERSION = "0.3.6"
3
3
 
4
4
  CHANGELOG =<<-END
5
5
  IMPORTANT CHANGES LATELY:
6
6
 
7
- # Added a "query" facet for free-form aggregations
7
+ * Fixed a bug: `Results::Item` was referencing Ruby classes incorrectly within Rails
8
+ * Added support for the Analyze API (#124)
9
+ * Added support for adding multiple filters (#122)
8
10
 
9
11
  END
10
12
  end
@@ -8,6 +8,8 @@ module Tire
8
8
  context "Filters" do
9
9
 
10
10
  should "filter the results" do
11
+ # 2.json > Begins with "T" and is tagged "ruby"
12
+
11
13
  s = Tire.search('articles-test') do
12
14
  query { string 'title:T*' }
13
15
  filter :terms, :tags => ['ruby']
@@ -17,7 +19,9 @@ module Tire
17
19
  assert_equal 'Two', s.results.first.title
18
20
  end
19
21
 
20
- should "filter the results with multiple filters" do
22
+ should "filter the results with multiple 'or' filters" do
23
+ # 4.json > Begins with "F" and is tagged "erlang"
24
+
21
25
  s = Tire.search('articles-test') do
22
26
  query { string 'title:F*' }
23
27
  filter :or, {:terms => {:tags => ['ruby']}},
@@ -28,10 +32,23 @@ module Tire
28
32
  assert_equal 'Four', s.results.first.title
29
33
  end
30
34
 
35
+ should "filter the results with multiple 'and' filters" do
36
+ # 5.json > Is tagged ["java", "javascript"] and is published on 2011-01-04
37
+
38
+ s = Tire.search('articles-test') do
39
+ filter :terms, :tags => ["java"]
40
+ filter :term, :published_on => "2011-01-04"
41
+ end
42
+
43
+ assert_equal 1, s.results.count
44
+ assert_equal 'Five', s.results.first.title
45
+ end
46
+
31
47
  should "not influence facets" do
32
48
  s = Tire.search('articles-test') do
33
49
  query { string 'title:T*' }
34
50
  filter :terms, :tags => ['ruby']
51
+
35
52
  facet('tags') { terms :tags }
36
53
  end
37
54
 
@@ -59,6 +59,43 @@ module Tire
59
59
  assert_nothing_raised { assert @index.close }
60
60
  end
61
61
 
62
+ context "analyze support" do
63
+ setup do
64
+ @mock_analyze_response = '{"tokens":[{"token":"foo","start_offset":0,"end_offset":4,"type":"<ALPHANUM>","position":1}]}'
65
+ end
66
+
67
+ should "send text to the Analyze API" do
68
+ Configuration.client.expects(:get).
69
+ with("#{Configuration.url}/dummy/_analyze?pretty=true", "foo bar").
70
+ returns(mock_response(@mock_analyze_response))
71
+
72
+ response = @index.analyze("foo bar")
73
+ p response
74
+ assert_equal 1, response['tokens'].size
75
+ end
76
+
77
+ should "properly encode parameters" do
78
+ Configuration.client.expects(:get).with do |url, payload|
79
+ url == "#{Configuration.url}/dummy/_analyze?analyzer=whitespace&pretty=true"
80
+ end.returns(mock_response(@mock_analyze_response))
81
+
82
+ @index.analyze("foo bar", :analyzer => 'whitespace')
83
+
84
+ Configuration.client.expects(:get).with do |url, payload|
85
+ url == "#{Configuration.url}/dummy/_analyze?field=title&pretty=true"
86
+ end.returns(mock_response(@mock_analyze_response))
87
+
88
+ @index.analyze("foo bar", :field => 'title')
89
+
90
+ Configuration.client.expects(:get).with do |url, payload|
91
+ url == "#{Configuration.url}/dummy/_analyze?analyzer=keyword&format=text&pretty=true"
92
+ end.returns(mock_response(@mock_analyze_response))
93
+
94
+ @index.analyze("foo bar", :analyzer => 'keyword', :format => 'text')
95
+ end
96
+
97
+ end
98
+
62
99
  context "mapping" do
63
100
 
64
101
  should "create index with mapping" do
@@ -347,6 +347,28 @@ module Tire
347
347
  assert_equal 100, ModelWithNestedMapping.mapping[:author][:properties][:last_name][:boost]
348
348
  end
349
349
 
350
+ should "define mapping for nested documents" do
351
+ class ::ModelWithNestedDocuments
352
+ extend ActiveModel::Naming
353
+ extend ActiveModel::Callbacks
354
+
355
+ include Tire::Model::Search
356
+ include Tire::Model::Callbacks
357
+
358
+ mapping do
359
+ indexes :comments, :type => 'nested', :include_in_parent => true do
360
+ indexes :author_name
361
+ indexes :body, :boost => 100
362
+ end
363
+ end
364
+
365
+ end
366
+
367
+ assert_equal 'nested', ModelWithNestedDocuments.mapping[:comments][:type]
368
+ assert_not_nil ModelWithNestedDocuments.mapping[:comments][:properties][:author_name]
369
+ assert_equal 100, ModelWithNestedDocuments.mapping[:comments][:properties][:body][:boost]
370
+ end
371
+
350
372
  end
351
373
 
352
374
  context "with settings" do
@@ -118,6 +118,12 @@ module Tire
118
118
  assert_equal 'fake_rails_models', ActiveModel::Naming.plural(@document)
119
119
  end
120
120
 
121
+ should "instantiate itself for deep hashes, not a Ruby class corresponding to type" do
122
+ document = Results::Item.new :_type => 'my_model', :title => 'Test', :author => { :name => 'John' }
123
+
124
+ assert_equal Tire::Results::Item, document.class
125
+ end
126
+
121
127
  end
122
128
 
123
129
  end
@@ -181,8 +181,27 @@ module Tire
181
181
  end
182
182
 
183
183
  assert_equal 1, s.filters.size
184
+
184
185
  assert_not_nil s.filters.first
185
186
  assert_not_nil s.filters.first[:terms]
187
+
188
+ assert_equal( {:terms => {:tags => ['foo']}}.to_json,
189
+ s.to_hash[:filter].to_json )
190
+ end
191
+
192
+ should "allow to add multiple filters" do
193
+ s = Search::Search.new('index') do
194
+ filter :terms, :tags => ['foo']
195
+ filter :term, :words => 125
196
+ end
197
+
198
+ assert_equal 2, s.filters.size
199
+
200
+ assert_not_nil s.filters.first[:terms]
201
+ assert_not_nil s.filters.last[:term]
202
+
203
+ assert_equal( { :and => [ {:terms => {:tags => ['foo']}}, {:term => {:words => 125}} ] }.to_json,
204
+ s.to_hash[:filter].to_json )
186
205
  end
187
206
 
188
207
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tire
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.5
4
+ version: 0.3.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-06 00:00:00.000000000 Z
12
+ date: 2011-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
16
- requirement: &70362722303360 !ruby/object:Gem::Requirement
16
+ requirement: &70265158105660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 0.9.2
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70362722303360
24
+ version_requirements: *70265158105660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rest-client
27
- requirement: &70362722302860 !ruby/object:Gem::Requirement
27
+ requirement: &70265158105100 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 1.6.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70362722302860
35
+ version_requirements: *70265158105100
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: multi_json
38
- requirement: &70362722302360 !ruby/object:Gem::Requirement
38
+ requirement: &70265158104600 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '1.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70362722302360
46
+ version_requirements: *70265158104600
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: activemodel
49
- requirement: &70362722301880 !ruby/object:Gem::Requirement
49
+ requirement: &70265158103940 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '3.0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70362722301880
57
+ version_requirements: *70265158103940
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bundler
60
- requirement: &70362722301400 !ruby/object:Gem::Requirement
60
+ requirement: &70265158102840 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ~>
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.0.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70362722301400
68
+ version_requirements: *70265158102840
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: yajl-ruby
71
- requirement: &70362722300940 !ruby/object:Gem::Requirement
71
+ requirement: &70265158097660 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.8.0
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *70362722300940
79
+ version_requirements: *70265158097660
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: shoulda
82
- requirement: &70362722300540 !ruby/object:Gem::Requirement
82
+ requirement: &70265158097280 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *70362722300540
90
+ version_requirements: *70265158097280
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: mocha
93
- requirement: &70362722300080 !ruby/object:Gem::Requirement
93
+ requirement: &70265158096780 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: '0'
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *70362722300080
101
+ version_requirements: *70265158096780
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: activerecord
104
- requirement: &70362722299560 !ruby/object:Gem::Requirement
104
+ requirement: &70265158096280 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 3.0.7
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *70362722299560
112
+ version_requirements: *70265158096280
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: mongoid
115
- requirement: &70362722288980 !ruby/object:Gem::Requirement
115
+ requirement: &70265158095780 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ~>
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 2.2.1
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *70362722288980
123
+ version_requirements: *70265158095780
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: sqlite3
126
- requirement: &70362722288600 !ruby/object:Gem::Requirement
126
+ requirement: &70265158095380 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: '0'
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *70362722288600
134
+ version_requirements: *70265158095380
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: supermodel
137
- requirement: &70362722288140 !ruby/object:Gem::Requirement
137
+ requirement: &70265158094900 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,10 +142,10 @@ dependencies:
142
142
  version: '0'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *70362722288140
145
+ version_requirements: *70265158094900
146
146
  - !ruby/object:Gem::Dependency
147
147
  name: sdoc
148
- requirement: &70362722287700 !ruby/object:Gem::Requirement
148
+ requirement: &70265158094460 !ruby/object:Gem::Requirement
149
149
  none: false
150
150
  requirements:
151
151
  - - ! '>='
@@ -153,10 +153,10 @@ dependencies:
153
153
  version: '0'
154
154
  type: :development
155
155
  prerelease: false
156
- version_requirements: *70362722287700
156
+ version_requirements: *70265158094460
157
157
  - !ruby/object:Gem::Dependency
158
158
  name: rdoc
159
- requirement: &70362722287280 !ruby/object:Gem::Requirement
159
+ requirement: &70265158094040 !ruby/object:Gem::Requirement
160
160
  none: false
161
161
  requirements:
162
162
  - - ! '>='
@@ -164,10 +164,10 @@ dependencies:
164
164
  version: '0'
165
165
  type: :development
166
166
  prerelease: false
167
- version_requirements: *70362722287280
167
+ version_requirements: *70265158094040
168
168
  - !ruby/object:Gem::Dependency
169
169
  name: rcov
170
- requirement: &70362722286860 !ruby/object:Gem::Requirement
170
+ requirement: &70265158093620 !ruby/object:Gem::Requirement
171
171
  none: false
172
172
  requirements:
173
173
  - - ! '>='
@@ -175,10 +175,10 @@ dependencies:
175
175
  version: '0'
176
176
  type: :development
177
177
  prerelease: false
178
- version_requirements: *70362722286860
178
+ version_requirements: *70265158093620
179
179
  - !ruby/object:Gem::Dependency
180
180
  name: turn
181
- requirement: &70362722286440 !ruby/object:Gem::Requirement
181
+ requirement: &70265158093160 !ruby/object:Gem::Requirement
182
182
  none: false
183
183
  requirements:
184
184
  - - ! '>='
@@ -186,7 +186,7 @@ dependencies:
186
186
  version: '0'
187
187
  type: :development
188
188
  prerelease: false
189
- version_requirements: *70362722286440
189
+ version_requirements: *70265158093160
190
190
  description: ! " Tire is a Ruby client for the ElasticSearch search engine/database.\n\n
191
191
  \ It provides Ruby-like API for fluent communication with the ElasticSearch server\n
192
192
  \ and blends with ActiveModel class for convenient usage in Rails applications.\n\n
@@ -297,8 +297,10 @@ homepage: http://github.com/karmi/tire
297
297
  licenses: []
298
298
  post_install_message: ! "================================================================================\n\n
299
299
  \ Please check the documentation at <http://karmi.github.com/tire/>.\n\n--------------------------------------------------------------------------------\n\n
300
- \ IMPORTANT CHANGES LATELY:\n\n # Added a \"query\" facet for free-form aggregations\n\n\n
301
- \ See the full changelog at <http://github.com/karmi/tire/commits/v0.3.5>.\n\n--------------------------------------------------------------------------------\n"
300
+ \ IMPORTANT CHANGES LATELY:\n\n * Fixed a bug: `Results::Item` was referencing
301
+ Ruby classes incorrectly within Rails\n * Added support for the Analyze API (#124)\n
302
+ \ * Added support for adding multiple filters (#122)\n\n\n See the full changelog
303
+ at <http://github.com/karmi/tire/commits/v0.3.6>.\n\n--------------------------------------------------------------------------------\n"
302
304
  rdoc_options:
303
305
  - --charset=UTF-8
304
306
  require_paths: