searchkick 0.8.3 → 0.8.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/README.md +77 -17
- data/lib/searchkick/model.rb +6 -4
- data/lib/searchkick/query.rb +36 -7
- data/lib/searchkick/reindex.rb +11 -4
- data/lib/searchkick/results.rb +17 -13
- data/lib/searchkick/version.rb +1 -1
- data/lib/searchkick.rb +4 -0
- data/test/boost_test.rb +9 -0
- data/test/highlight_test.rb +12 -0
- data/test/index_test.rb +15 -0
- data/test/match_test.rb +7 -0
- data/test/sql_test.rb +7 -0
- data/test/test_helper.rb +4 -1
- metadata +2 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c50ef339d04f201523ff1f41aad11277d7168dab
|
|
4
|
+
data.tar.gz: d7f79bf282327a781e23475f64b7530dfac6beab
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 61072c05e3aa82903b699e2062dc0a2944f7fcec20545709d2b83f1f0a760778adffbc7cf7002815c56c2ba6f9484de13f35134c484842ebbf56785d549a6883
|
|
7
|
+
data.tar.gz: 5c95dd8df5ead5050d2b24175e01b6ad197d7f430f92554f2330cb3b0976360ab4182d956e62ae734ce38b77985eb84f6c0e7e95a0d147d18f061e0964ee61e6
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
## 0.8.5
|
|
2
|
+
|
|
3
|
+
- Added support for Elasticsearch 1.4
|
|
4
|
+
- Added `unsearchable` option
|
|
5
|
+
- Added `select: true` option
|
|
6
|
+
- Added `body` option
|
|
7
|
+
|
|
8
|
+
## 0.8.4
|
|
9
|
+
|
|
10
|
+
- Added `boost_by_distance`
|
|
11
|
+
- More flexible highlight options
|
|
12
|
+
- Better `env` logic
|
|
13
|
+
|
|
1
14
|
## 0.8.3
|
|
2
15
|
|
|
3
16
|
- Added support for ActiveJob
|
data/README.md
CHANGED
|
@@ -124,7 +124,7 @@ Boost important fields
|
|
|
124
124
|
fields: ["title^10", "description"]
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
Boost by the value of a field
|
|
127
|
+
Boost by the value of a field (field must be numeric)
|
|
128
128
|
|
|
129
129
|
```ruby
|
|
130
130
|
boost_by: [:orders_count] # give popular documents a little boost
|
|
@@ -553,7 +553,7 @@ Highlight the search query in the results.
|
|
|
553
553
|
bands = Band.search "cinema", fields: [:name], highlight: true
|
|
554
554
|
```
|
|
555
555
|
|
|
556
|
-
**Note:** The `fields` option is required.
|
|
556
|
+
**Note:** The `fields` option is required, unless highlight options are given - see below.
|
|
557
557
|
|
|
558
558
|
View the highlighted fields with:
|
|
559
559
|
|
|
@@ -569,6 +569,20 @@ To change the tag, use:
|
|
|
569
569
|
Band.search "cinema", fields: [:name], highlight: {tag: "<strong>"}
|
|
570
570
|
```
|
|
571
571
|
|
|
572
|
+
To highlight and search different fields, use:
|
|
573
|
+
|
|
574
|
+
```ruby
|
|
575
|
+
Band.search "cinema", fields: [:name], highlight: {fields: [:description]}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Additional options, including fragment size, can be specified for each field:
|
|
579
|
+
|
|
580
|
+
```ruby
|
|
581
|
+
Band.search "cinema", fields: [:name], highlight: {fields: {name: {fragment_size: 200}}}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
You can find available highlight options in the [Elasticsearch reference](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-request-highlighting.html#_highlighted_fragments).
|
|
585
|
+
|
|
572
586
|
### Similar Items
|
|
573
587
|
|
|
574
588
|
Find similar items.
|
|
@@ -602,6 +616,20 @@ Bounded by a box
|
|
|
602
616
|
City.search "san", where: {location: {top_left: [38, -123], bottom_right: [37, -122]}}
|
|
603
617
|
```
|
|
604
618
|
|
|
619
|
+
### Boost By Distance
|
|
620
|
+
|
|
621
|
+
Boost results by distance - closer results are boosted more
|
|
622
|
+
|
|
623
|
+
```ruby
|
|
624
|
+
City.search "san", boost_by_distance: {field: :location, origin: [37, -122]}
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
Also supports [additional options](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#_decay_functions)
|
|
628
|
+
|
|
629
|
+
```ruby
|
|
630
|
+
City.search "san", boost_by_distance: {field: :location, origin: [37, -122], function: :linear, scale: "30mi", decay: 0.5}
|
|
631
|
+
```
|
|
632
|
+
|
|
605
633
|
## Inheritance
|
|
606
634
|
|
|
607
635
|
Searchkick supports single table inheritance.
|
|
@@ -703,15 +731,20 @@ rake searchkick:reindex CLASS=Product
|
|
|
703
731
|
|
|
704
732
|
### Performance
|
|
705
733
|
|
|
706
|
-
For the best performance, add [
|
|
734
|
+
For the best performance, add [Typhoeus](https://github.com/typhoeus/typhoeus) to your Gemfile.
|
|
707
735
|
|
|
708
736
|
```ruby
|
|
709
|
-
gem '
|
|
737
|
+
gem 'typhoeus'
|
|
710
738
|
```
|
|
711
739
|
|
|
712
|
-
|
|
740
|
+
And create an initializer with:
|
|
741
|
+
|
|
742
|
+
```ruby
|
|
743
|
+
require "typhoeus/adapters/faraday"
|
|
744
|
+
Ethon.logger = Logger.new("/dev/null")
|
|
745
|
+
```
|
|
713
746
|
|
|
714
|
-
**Note:**
|
|
747
|
+
**Note:** Typhoeus is not available for Windows.
|
|
715
748
|
|
|
716
749
|
### Automatic Failover
|
|
717
750
|
|
|
@@ -723,10 +756,26 @@ Searchkick.client = Elasticsearch::Client.new(hosts: ["localhost:9200", "localho
|
|
|
723
756
|
|
|
724
757
|
See [elasticsearch-transport](https://github.com/elasticsearch/elasticsearch-ruby/blob/master/elasticsearch-transport) for a complete list of options.
|
|
725
758
|
|
|
759
|
+
### Lograge
|
|
760
|
+
|
|
761
|
+
Add the following to `config/environments/production.rb`:
|
|
762
|
+
|
|
763
|
+
```ruby
|
|
764
|
+
config.lograge.custom_options = lambda do |event|
|
|
765
|
+
options = {}
|
|
766
|
+
options[:search] = event.payload[:searchkick_runtime] if event.payload[:searchkick_runtime].to_f > 0
|
|
767
|
+
options
|
|
768
|
+
end
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
See [Production Rails](https://github.com/ankane/production_rails) for other good practices.
|
|
772
|
+
|
|
726
773
|
## Advanced
|
|
727
774
|
|
|
728
775
|
Prefer to use the [Elasticsearch DSL](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-queries.html) but still want awesome features like zero-downtime reindexing?
|
|
729
776
|
|
|
777
|
+
### Advanced Mapping
|
|
778
|
+
|
|
730
779
|
Create a custom mapping:
|
|
731
780
|
|
|
732
781
|
```ruby
|
|
@@ -741,32 +790,35 @@ class Product < ActiveRecord::Base
|
|
|
741
790
|
end
|
|
742
791
|
```
|
|
743
792
|
|
|
744
|
-
|
|
793
|
+
To keep the mappings and settings generated by Searchkick, use:
|
|
745
794
|
|
|
746
795
|
```ruby
|
|
747
|
-
|
|
796
|
+
class Product < ActiveRecord::Base
|
|
797
|
+
searchkick merge_mappings: true, mappings: {...}
|
|
798
|
+
end
|
|
748
799
|
```
|
|
749
800
|
|
|
750
|
-
|
|
801
|
+
### Advanced Search
|
|
802
|
+
|
|
803
|
+
And use the `body` option to search:
|
|
751
804
|
|
|
752
805
|
```ruby
|
|
753
|
-
products.
|
|
806
|
+
products = Product.search body: {match: {name: "milk"}}
|
|
754
807
|
```
|
|
755
808
|
|
|
756
|
-
|
|
809
|
+
View the response with:
|
|
757
810
|
|
|
758
811
|
```ruby
|
|
759
|
-
|
|
760
|
-
searchkick merge_mappings: true, mappings: {...}
|
|
761
|
-
end
|
|
812
|
+
products.response
|
|
762
813
|
```
|
|
763
814
|
|
|
764
815
|
To modify the query generated by Searchkick, use:
|
|
765
816
|
|
|
766
817
|
```ruby
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
818
|
+
products =
|
|
819
|
+
Product.search "2% Milk" do |body|
|
|
820
|
+
body[:query] = {match_all: {}}
|
|
821
|
+
end
|
|
770
822
|
```
|
|
771
823
|
|
|
772
824
|
## Reference
|
|
@@ -850,6 +902,14 @@ class Product < ActiveRecord::Base
|
|
|
850
902
|
end
|
|
851
903
|
```
|
|
852
904
|
|
|
905
|
+
Make fields unsearchable but include in the source
|
|
906
|
+
|
|
907
|
+
```ruby
|
|
908
|
+
class Product < ActiveRecord::Base
|
|
909
|
+
searchkick unsearchable: [:color]
|
|
910
|
+
end
|
|
911
|
+
```
|
|
912
|
+
|
|
853
913
|
Reindex asynchronously
|
|
854
914
|
|
|
855
915
|
```ruby
|
data/lib/searchkick/model.rb
CHANGED
|
@@ -5,15 +5,14 @@ module Searchkick
|
|
|
5
5
|
raise "Only call searchkick once per model" if respond_to?(:searchkick_index)
|
|
6
6
|
|
|
7
7
|
class_eval do
|
|
8
|
-
cattr_reader :searchkick_options, :
|
|
8
|
+
cattr_reader :searchkick_options, :searchkick_klass
|
|
9
9
|
|
|
10
10
|
callbacks = options.has_key?(:callbacks) ? options[:callbacks] : true
|
|
11
11
|
|
|
12
12
|
class_variable_set :@@searchkick_options, options.dup
|
|
13
|
-
class_variable_set :@@searchkick_env, ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
|
|
14
13
|
class_variable_set :@@searchkick_klass, self
|
|
15
14
|
class_variable_set :@@searchkick_callbacks, callbacks
|
|
16
|
-
class_variable_set :@@searchkick_index, options[:index_name] || [options[:index_prefix], model_name.plural,
|
|
15
|
+
class_variable_set :@@searchkick_index, options[:index_name] || [options[:index_prefix], model_name.plural, Searchkick.env].compact.join("_")
|
|
17
16
|
|
|
18
17
|
def self.searchkick_index
|
|
19
18
|
index = class_variable_get :@@searchkick_index
|
|
@@ -21,8 +20,11 @@ module Searchkick
|
|
|
21
20
|
Searchkick::Index.new(index)
|
|
22
21
|
end
|
|
23
22
|
|
|
24
|
-
define_singleton_method(Searchkick.search_method_name) do |term = nil, options={}|
|
|
23
|
+
define_singleton_method(Searchkick.search_method_name) do |term = nil, options={}, &block|
|
|
25
24
|
query = Searchkick::Query.new(self, term, options)
|
|
25
|
+
if block
|
|
26
|
+
block.call(query.body)
|
|
27
|
+
end
|
|
26
28
|
if options[:execute] == false
|
|
27
29
|
query
|
|
28
30
|
else
|
data/lib/searchkick/query.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Searchkick
|
|
|
16
16
|
@options = options
|
|
17
17
|
|
|
18
18
|
below12 = Gem::Version.new(Searchkick.server_version) < Gem::Version.new("1.2")
|
|
19
|
+
below14 = Gem::Version.new(Searchkick.server_version) < Gem::Version.new("1.4")
|
|
19
20
|
|
|
20
21
|
boost_fields = {}
|
|
21
22
|
fields =
|
|
@@ -56,6 +57,7 @@ module Searchkick
|
|
|
56
57
|
all = term == "*"
|
|
57
58
|
facet_limits = {}
|
|
58
59
|
|
|
60
|
+
options[:json] ||= options[:body]
|
|
59
61
|
if options[:json]
|
|
60
62
|
payload = options[:json]
|
|
61
63
|
else
|
|
@@ -209,6 +211,21 @@ module Searchkick
|
|
|
209
211
|
}
|
|
210
212
|
end
|
|
211
213
|
|
|
214
|
+
boost_by_distance = options[:boost_by_distance]
|
|
215
|
+
if boost_by_distance
|
|
216
|
+
boost_by_distance = {function: :gauss, scale: "5mi"}.merge(boost_by_distance)
|
|
217
|
+
if !boost_by_distance[:field] or !boost_by_distance[:origin]
|
|
218
|
+
raise ArgumentError, "boost_by_distance requires :field and :origin"
|
|
219
|
+
end
|
|
220
|
+
function_params = boost_by_distance.select{|k,v| [:origin, :scale, :offset, :decay].include?(k) }
|
|
221
|
+
function_params[:origin] = function_params[:origin].reverse
|
|
222
|
+
custom_filters << {
|
|
223
|
+
boost_by_distance[:function] => {
|
|
224
|
+
boost_by_distance[:field] => function_params
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
end
|
|
228
|
+
|
|
212
229
|
if custom_filters.any?
|
|
213
230
|
payload = {
|
|
214
231
|
function_score: {
|
|
@@ -264,7 +281,7 @@ module Searchkick
|
|
|
264
281
|
payload[:facets][field] = {
|
|
265
282
|
terms_stats: {
|
|
266
283
|
key_field: field,
|
|
267
|
-
value_script: "doc.score",
|
|
284
|
+
value_script: below14 ? "doc.score" : "_score",
|
|
268
285
|
size: size
|
|
269
286
|
}
|
|
270
287
|
}
|
|
@@ -320,18 +337,30 @@ module Searchkick
|
|
|
320
337
|
payload[:highlight] = {
|
|
321
338
|
fields: Hash[ fields.map{|f| [f, {}] } ]
|
|
322
339
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
340
|
+
|
|
341
|
+
if options[:highlight].is_a?(Hash)
|
|
342
|
+
if tag = options[:highlight][:tag]
|
|
343
|
+
payload[:highlight][:pre_tags] = [tag]
|
|
344
|
+
payload[:highlight][:post_tags] = [tag.to_s.gsub(/\A</, "</")]
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
highlight_fields = options[:highlight][:fields]
|
|
348
|
+
if highlight_fields
|
|
349
|
+
payload[:highlight][:fields] = {}
|
|
350
|
+
|
|
351
|
+
highlight_fields.each do |name, opts|
|
|
352
|
+
payload[:highlight][:fields]["#{name}.analyzed"] = opts || {}
|
|
353
|
+
end
|
|
354
|
+
end
|
|
326
355
|
end
|
|
327
356
|
end
|
|
328
357
|
|
|
329
358
|
# An empty array will cause only the _id and _type for each hit to be returned
|
|
330
359
|
# http://www.elasticsearch.org/guide/reference/api/search/fields/
|
|
331
|
-
if
|
|
360
|
+
if options[:select]
|
|
361
|
+
payload[:fields] = options[:select] if options[:select] != true
|
|
362
|
+
elsif load
|
|
332
363
|
payload[:fields] = []
|
|
333
|
-
elsif options[:select]
|
|
334
|
-
payload[:fields] = options[:select]
|
|
335
364
|
end
|
|
336
365
|
|
|
337
366
|
if options[:type] or klass != searchkick_klass
|
data/lib/searchkick/reindex.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Searchkick
|
|
|
7
7
|
skip_import = options[:import] == false
|
|
8
8
|
|
|
9
9
|
alias_name = searchkick_index.name
|
|
10
|
-
new_name = alias_name
|
|
10
|
+
new_name = "#{alias_name}_#{Time.now.strftime('%Y%m%d%H%M%S%L')}"
|
|
11
11
|
index = Searchkick::Index.new(new_name)
|
|
12
12
|
|
|
13
13
|
clean_indices
|
|
@@ -40,7 +40,7 @@ module Searchkick
|
|
|
40
40
|
# remove old indices that start w/ index_name
|
|
41
41
|
def clean_indices
|
|
42
42
|
all_indices = Searchkick.client.indices.get_aliases
|
|
43
|
-
indices = all_indices.select{|k, v| v["aliases"].empty? && k =~ /\A#{Regexp.escape(searchkick_index.name)}_\d{14,17}\z/ }.keys
|
|
43
|
+
indices = all_indices.select{|k, v| (v.empty? || v["aliases"].empty?) && k =~ /\A#{Regexp.escape(searchkick_index.name)}_\d{14,17}\z/ }.keys
|
|
44
44
|
indices.each do |index|
|
|
45
45
|
Searchkick::Index.new(index).delete
|
|
46
46
|
end
|
|
@@ -203,7 +203,7 @@ module Searchkick
|
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
if
|
|
206
|
+
if Searchkick.env == "test"
|
|
207
207
|
settings.merge!(number_of_shards: 1, number_of_replicas: 0)
|
|
208
208
|
end
|
|
209
209
|
|
|
@@ -288,12 +288,19 @@ module Searchkick
|
|
|
288
288
|
mapping[field] = field_mapping
|
|
289
289
|
end
|
|
290
290
|
|
|
291
|
-
(options[:locations] || []).each do |field|
|
|
291
|
+
(options[:locations] || []).map(&:to_s).each do |field|
|
|
292
292
|
mapping[field] = {
|
|
293
293
|
type: "geo_point"
|
|
294
294
|
}
|
|
295
295
|
end
|
|
296
296
|
|
|
297
|
+
(options[:unsearchable] || []).map(&:to_s).each do |field|
|
|
298
|
+
mapping[field] = {
|
|
299
|
+
type: "string",
|
|
300
|
+
index: "no"
|
|
301
|
+
}
|
|
302
|
+
end
|
|
303
|
+
|
|
297
304
|
mappings = {
|
|
298
305
|
_default_: {
|
|
299
306
|
properties: mapping,
|
data/lib/searchkick/results.rb
CHANGED
|
@@ -26,17 +26,7 @@ module Searchkick
|
|
|
26
26
|
if options[:includes]
|
|
27
27
|
records = records.includes(options[:includes])
|
|
28
28
|
end
|
|
29
|
-
results[type] =
|
|
30
|
-
if records.respond_to?(:primary_key) and records.primary_key
|
|
31
|
-
# ActiveRecord
|
|
32
|
-
records.where(records.primary_key => grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
33
|
-
elsif records.respond_to?(:all) and records.all.respond_to?(:for_ids)
|
|
34
|
-
# Mongoid 2
|
|
35
|
-
records.all.for_ids(grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
36
|
-
else
|
|
37
|
-
# Mongoid 3+
|
|
38
|
-
records.queryable.for_ids(grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
39
|
-
end
|
|
29
|
+
results[type] = results_query(records, grouped_hits)
|
|
40
30
|
end
|
|
41
31
|
|
|
42
32
|
# sort
|
|
@@ -137,11 +127,25 @@ module Searchkick
|
|
|
137
127
|
next_page.nil?
|
|
138
128
|
end
|
|
139
129
|
|
|
140
|
-
protected
|
|
141
|
-
|
|
142
130
|
def hits
|
|
143
131
|
@response["hits"]["hits"]
|
|
144
132
|
end
|
|
145
133
|
|
|
134
|
+
private
|
|
135
|
+
|
|
136
|
+
def results_query(records, grouped_hits)
|
|
137
|
+
if records.respond_to?(:primary_key) and records.primary_key
|
|
138
|
+
# ActiveRecord
|
|
139
|
+
records.where(records.primary_key => grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
140
|
+
elsif records.respond_to?(:all) and records.all.respond_to?(:for_ids)
|
|
141
|
+
# Mongoid 2
|
|
142
|
+
records.all.for_ids(grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
143
|
+
elsif records.respond_to?(:queryable)
|
|
144
|
+
# Mongoid 3+
|
|
145
|
+
records.queryable.for_ids(grouped_hits.map{|hit| hit["_id"] }).to_a
|
|
146
|
+
else
|
|
147
|
+
raise "Not sure how to load records"
|
|
148
|
+
end
|
|
149
|
+
end
|
|
146
150
|
end
|
|
147
151
|
end
|
data/lib/searchkick/version.rb
CHANGED
data/lib/searchkick.rb
CHANGED
data/test/boost_test.rb
CHANGED
|
@@ -104,4 +104,13 @@ class TestBoost < Minitest::Test
|
|
|
104
104
|
assert_first "tomato", "Tomato B", boost_where: {user_ids: {value: 2, factor: 10}}
|
|
105
105
|
end
|
|
106
106
|
|
|
107
|
+
def test_boost_by_distance
|
|
108
|
+
store [
|
|
109
|
+
{name: "San Francisco", latitude: 37.7833, longitude: -122.4167},
|
|
110
|
+
{name: "San Antonio", latitude: 29.4167, longitude: -98.5000},
|
|
111
|
+
{name: "San Marino", latitude: 43.9333, longitude: 12.4667}
|
|
112
|
+
]
|
|
113
|
+
assert_order "san", ["San Francisco", "San Antonio", "San Marino"], boost_by_distance: {field: :location, origin: [37, -122], scale: "1000mi"}
|
|
114
|
+
end
|
|
115
|
+
|
|
107
116
|
end
|
data/test/highlight_test.rb
CHANGED
|
@@ -19,6 +19,18 @@ class TestHighlight < Minitest::Test
|
|
|
19
19
|
assert_equal "<em>Cinema</em> Orange", highlight[:color]
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def test_fields
|
|
23
|
+
store [{name: "Two Door Cinema Club", color: "Cinema Orange"}]
|
|
24
|
+
highlight = Product.search("cinema", fields: [:name, :color], highlight: {fields: [:name]}).with_details.first[1][:highlight]
|
|
25
|
+
assert_equal "Two Door <em>Cinema</em> Club", highlight[:name]
|
|
26
|
+
assert_equal nil, highlight[:color]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_field_options
|
|
30
|
+
store_names ["Two Door Cinema Club are a Northern Irish indie rock band"]
|
|
31
|
+
assert_equal "Two Door <em>Cinema</em> Club are", Product.search("cinema", fields: [:name], highlight: {fields: {name: {fragment_size: 20}}}).with_details.first[1][:highlight][:name]
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
def test_multiple_words
|
|
23
35
|
store_names ["Hello World Hello"]
|
|
24
36
|
assert_equal "<em>Hello</em> World <em>Hello</em>", Product.search("hello", fields: [:name], highlight: true).with_details.first[1][:highlight][:name]
|
data/test/index_test.rb
CHANGED
|
@@ -41,6 +41,21 @@ class TestIndex < Minitest::Test
|
|
|
41
41
|
assert_equal ["Dollar Tree"], Store.search(json: {query: {match: {name: "Dollar Tree"}}}, load: false).map(&:name)
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
+
def test_body
|
|
45
|
+
store_names ["Dollar Tree"], Store
|
|
46
|
+
assert_equal [], Store.search(query: {match: {name: "dollar"}}).map(&:name)
|
|
47
|
+
assert_equal ["Dollar Tree"], Store.search(body: {query: {match: {name: "Dollar Tree"}}}, load: false).map(&:name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def test_block
|
|
51
|
+
store_names ["Dollar Tree"]
|
|
52
|
+
products =
|
|
53
|
+
Product.search "boom" do |body|
|
|
54
|
+
body[:query] = {match_all: {}}
|
|
55
|
+
end
|
|
56
|
+
assert_equal ["Dollar Tree"], products.map(&:name)
|
|
57
|
+
end
|
|
58
|
+
|
|
44
59
|
def test_tokens
|
|
45
60
|
assert_equal ["dollar", "dollartre", "tree"], Product.searchkick_index.tokens("Dollar Tree")
|
|
46
61
|
end
|
data/test/match_test.rb
CHANGED
data/test/sql_test.rb
CHANGED
|
@@ -298,6 +298,13 @@ class TestSql < Minitest::Test
|
|
|
298
298
|
assert_equal [1, 2], result.user_ids
|
|
299
299
|
end
|
|
300
300
|
|
|
301
|
+
def test_select_all
|
|
302
|
+
store [{name: "Product A", user_ids: [1, 2]}]
|
|
303
|
+
hit = Product.search("product", select: true).hits.first
|
|
304
|
+
assert_equal hit["_source"]["name"], "Product A"
|
|
305
|
+
assert_equal hit["_source"]["user_ids"], [1, 2]
|
|
306
|
+
end
|
|
307
|
+
|
|
301
308
|
def test_nested_object
|
|
302
309
|
aisle = {"id" => 1, "name" => "Frozen"}
|
|
303
310
|
store [{name: "Product A", aisle: aisle}]
|
data/test/test_helper.rb
CHANGED
|
@@ -53,6 +53,7 @@ if defined?(Mongoid)
|
|
|
53
53
|
field :color
|
|
54
54
|
field :latitude, type: BigDecimal
|
|
55
55
|
field :longitude, type: BigDecimal
|
|
56
|
+
field :description
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
class Store
|
|
@@ -95,6 +96,7 @@ else
|
|
|
95
96
|
t.string :color
|
|
96
97
|
t.decimal :latitude, precision: 10, scale: 7
|
|
97
98
|
t.decimal :longitude, precision: 10, scale: 7
|
|
99
|
+
t.text :description
|
|
98
100
|
t.timestamps
|
|
99
101
|
end
|
|
100
102
|
|
|
@@ -146,7 +148,8 @@ class Product
|
|
|
146
148
|
word_start: [:name],
|
|
147
149
|
word_middle: [:name],
|
|
148
150
|
word_end: [:name],
|
|
149
|
-
highlight: [:name]
|
|
151
|
+
highlight: [:name],
|
|
152
|
+
unsearchable: [:description]
|
|
150
153
|
|
|
151
154
|
attr_accessor :conversions, :user_ids, :aisle
|
|
152
155
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: searchkick
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew Kane
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2014-
|
|
11
|
+
date: 2014-11-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activemodel
|
|
@@ -188,4 +188,3 @@ test_files:
|
|
|
188
188
|
- test/suggest_test.rb
|
|
189
189
|
- test/synonyms_test.rb
|
|
190
190
|
- test/test_helper.rb
|
|
191
|
-
has_rdoc:
|