searchkick 2.3.2 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8f081bd9d81b729d9bd3610154f95aeb355684f8
4
- data.tar.gz: 88702f0b0417396e58697bd86919b92f716d470b
3
+ metadata.gz: 4bbb1863e16cb46d246eb067805b4a2cc1471c68
4
+ data.tar.gz: ea1bc2af0dcb8eb2e059aae9586697086a3cbc0e
5
5
  SHA512:
6
- metadata.gz: bbebeb45ba1cff82280c6d0eab7f25ac42dbc6f22b600a23f583b4da36fa6e42a4ebab6d9e149087192ca765dd75aadd5eaa4fb3b5add5e8ce3613ff8f91a85f
7
- data.tar.gz: d643fbc24e36968f2820b92875a28fbf215e68d752717d4d2fa8a8fcd7efa32009f03a4c8a983d88666ab7c18e2602e58895f6c36e4934b651c0a838ae4f45ab
6
+ metadata.gz: 50d82877150dc9a875e8d67539f1992d29870b8cef227b7e81eb1c05f8e6e8346b952914035af8d2b1b5177cd8c730f5e55eb57c0a725feeaf0a2d6bfad6a29a
7
+ data.tar.gz: 45bea9181b909710ff9f446df5151f536e002caf11249d3d53c40ea7a1eecb465e797acf896c23ab15fc9b54f7028ce9d0244c1680dcb6f5281d7f3dc4f6d754
data/.travis.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  sudo: false
2
2
  language: ruby
3
- rvm: 2.3.1
3
+ rvm: 2.4.2
4
4
  services:
5
5
  - mongodb
6
6
  - redis-server
@@ -20,7 +20,7 @@ gemfile:
20
20
  - test/gemfiles/mongoid5.gemfile
21
21
  - test/gemfiles/mongoid6.gemfile
22
22
  env:
23
- - ELASTICSEARCH_VERSION=5.5.0
23
+ - ELASTICSEARCH_VERSION=6.0.0
24
24
  jdk: oraclejdk8
25
25
  matrix:
26
26
  include:
@@ -28,12 +28,11 @@ matrix:
28
28
  env: ELASTICSEARCH_VERSION=2.0.0
29
29
  jdk: oraclejdk7
30
30
  - gemfile: Gemfile
31
- env: ELASTICSEARCH_VERSION=2.4.3
31
+ env: ELASTICSEARCH_VERSION=2.4.6
32
32
  jdk: oraclejdk7
33
33
  - gemfile: Gemfile
34
34
  env: ELASTICSEARCH_VERSION=5.0.1
35
35
  jdk: oraclejdk8
36
- allow_failures:
37
36
  - gemfile: Gemfile
38
- env: ELASTICSEARCH_VERSION=6.0.0-beta1
37
+ env: ELASTICSEARCH_VERSION=5.6.4
39
38
  jdk: oraclejdk8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ## 2.4.0
2
+
3
+ - Fixed `similar` for Elasticsearch 6
4
+ - Added `inheritance` option
5
+ - Added `_type` option
6
+ - Fixed `Must specify fields to search` error when searching `*`
7
+
1
8
  ## 2.3.2
2
9
 
3
10
  - Added `_all` and `default_fields` options
data/README.md CHANGED
@@ -54,12 +54,12 @@ Add this line to your application’s Gemfile:
54
54
  gem 'searchkick'
55
55
  ```
56
56
 
57
- The latest version works with Elasticsearch 2 and 5. For Elasticsearch 1, use version 1.5.1 and [this readme](https://github.com/ankane/searchkick/blob/v1.5.1/README.md).
57
+ The latest version works with Elasticsearch 2, 5, and 6. For Elasticsearch 1, use version 1.5.1 and [this readme](https://github.com/ankane/searchkick/blob/v1.5.1/README.md).
58
58
 
59
59
  Add searchkick to models you want to search.
60
60
 
61
61
  ```ruby
62
- class Product < ActiveRecord::Base
62
+ class Product < ApplicationRecord
63
63
  searchkick
64
64
  end
65
65
  ```
@@ -73,7 +73,7 @@ Product.reindex
73
73
  And to query, use:
74
74
 
75
75
  ```ruby
76
- products = Product.search "apples"
76
+ products = Product.search("apples", fields: [:name])
77
77
  products.each do |product|
78
78
  puts product.name
79
79
  end
@@ -130,6 +130,8 @@ Select
130
130
  select: [:name]
131
131
  ```
132
132
 
133
+ [These source filtering options are supported](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html)
134
+
133
135
  ### Results
134
136
 
135
137
  Searches return a `Searchkick::Results` object. This responds like an array to most methods.
@@ -236,7 +238,7 @@ Product.search "fresh honey", operator: "or" # fresh OR honey
236
238
  By default, results must match the entire word - `back` will not match `backpack`. You can change this behavior with:
237
239
 
238
240
  ```ruby
239
- class Product < ActiveRecord::Base
241
+ class Product < ApplicationRecord
240
242
  searchkick word_start: [:name]
241
243
  end
242
244
  ```
@@ -261,7 +263,7 @@ Available options are:
261
263
 
262
264
  ### Exact Matches
263
265
 
264
- To match a field exactly (case-insensitive), use:
266
+ To match a field exactly (case-sensitive), use:
265
267
 
266
268
  ```ruby
267
269
  User.search query, fields: [{email: :exact}, :name]
@@ -280,7 +282,7 @@ User.search "fresh honey", match: :phrase
280
282
  Searchkick defaults to English for stemming. To change this, use:
281
283
 
282
284
  ```ruby
283
- class Product < ActiveRecord::Base
285
+ class Product < ApplicationRecord
284
286
  searchkick language: "german"
285
287
  end
286
288
  ```
@@ -290,7 +292,7 @@ end
290
292
  ### Synonyms
291
293
 
292
294
  ```ruby
293
- class Product < ActiveRecord::Base
295
+ class Product < ApplicationRecord
294
296
  searchkick synonyms: [["scallion", "green onion"], ["qtip", "cotton swab"]]
295
297
  end
296
298
  ```
@@ -314,7 +316,7 @@ synonyms: ["lightbulb => halogenlamp"]
314
316
  The above approach works well when your synonym list is static, but in practice, this is often not the case. When you analyze search conversions, you often want to add new synonyms or tags without a full reindex. You can use a library like [ActsAsTaggableOn](https://github.com/mbleigh/acts-as-taggable-on) and do:
315
317
 
316
318
  ```ruby
317
- class Product < ActiveRecord::Base
319
+ class Product < ApplicationRecord
318
320
  acts_as_taggable
319
321
  scope :search_import, -> { includes(:tags) }
320
322
 
@@ -348,7 +350,7 @@ mv prolog/wn_s.pl /var/lib
348
350
  Tell each model to use it:
349
351
 
350
352
  ```ruby
351
- class Product < ActiveRecord::Base
353
+ class Product < ApplicationRecord
352
354
  searchkick wordnet: true
353
355
  end
354
356
  ```
@@ -417,7 +419,7 @@ Product.search "🍨🍰", emoji: true
417
419
  Control what data is indexed with the `search_data` method. Call `Product.reindex` after changing this method.
418
420
 
419
421
  ```ruby
420
- class Product < ActiveRecord::Base
422
+ class Product < ApplicationRecord
421
423
  belongs_to :department
422
424
 
423
425
  def search_data
@@ -433,7 +435,7 @@ end
433
435
  Searchkick uses `find_in_batches` to import documents. To eager load associations, use the `search_import` scope.
434
436
 
435
437
  ```ruby
436
- class Product < ActiveRecord::Base
438
+ class Product < ApplicationRecord
437
439
  scope :search_import, -> { includes(:department) }
438
440
  end
439
441
  ```
@@ -441,7 +443,7 @@ end
441
443
  By default, all records are indexed. To control which records are indexed, use the `should_index?` method together with the `search_import` scope.
442
444
 
443
445
  ```ruby
444
- class Product < ActiveRecord::Base
446
+ class Product < ApplicationRecord
445
447
  scope :search_import, -> { where(active: true) }
446
448
 
447
449
  def should_index?
@@ -483,7 +485,7 @@ There are four strategies for keeping the index synced with your database.
483
485
  Use background jobs for better performance
484
486
 
485
487
  ```ruby
486
- class Product < ActiveRecord::Base
488
+ class Product < ApplicationRecord
487
489
  searchkick callbacks: :async
488
490
  end
489
491
  ```
@@ -499,7 +501,7 @@ There are four strategies for keeping the index synced with your database.
499
501
  Turn off automatic syncing
500
502
 
501
503
  ```ruby
502
- class Product < ActiveRecord::Base
504
+ class Product < ApplicationRecord
503
505
  searchkick callbacks: false
504
506
  end
505
507
  ```
@@ -525,7 +527,7 @@ end
525
527
  Data is **not** automatically synced when an association is updated. If this is desired, add a callback to reindex:
526
528
 
527
529
  ```ruby
528
- class Image < ActiveRecord::Base
530
+ class Image < ApplicationRecord
529
531
  belongs_to :product
530
532
 
531
533
  after_commit :reindex_product
@@ -564,7 +566,7 @@ You do **not** need to clean up the search queries. Searchkick automatically tre
564
566
  Next, add conversions to the index.
565
567
 
566
568
  ```ruby
567
- class Product < ActiveRecord::Base
569
+ class Product < ApplicationRecord
568
570
  has_many :searches, class_name: "Searchjoy::Search", as: :convertable
569
571
 
570
572
  searchkick conversions: ["conversions"] # name of field
@@ -592,7 +594,7 @@ rake searchkick:reindex CLASS=Product
592
594
  Order results differently for each user. For example, show a user’s previously purchased products before other results.
593
595
 
594
596
  ```ruby
595
- class Product < ActiveRecord::Base
597
+ class Product < ApplicationRecord
596
598
  def search_data
597
599
  {
598
600
  name: name,
@@ -621,7 +623,7 @@ Autocomplete predicts what a user will type, making the search experience faster
621
623
  First, specify which fields use this feature. This is necessary since autocomplete can increase the index size significantly, but don’t worry - this gives you blazing faster queries.
622
624
 
623
625
  ```ruby
624
- class Movie < ActiveRecord::Base
626
+ class Movie < ApplicationRecord
625
627
  searchkick word_start: [:title, :director]
626
628
  end
627
629
  ```
@@ -681,7 +683,7 @@ Then add the search box and JavaScript code to a view.
681
683
  ![Suggest](https://raw.githubusercontent.com/ankane/searchkick/gh-pages/recursion.png)
682
684
 
683
685
  ```ruby
684
- class Product < ActiveRecord::Base
686
+ class Product < ApplicationRecord
685
687
  searchkick suggest: [:name] # fields to generate suggestions
686
688
  end
687
689
  ```
@@ -819,7 +821,7 @@ Product.search "pear", aggs: {products_per_year: {date_histogram: {field: :creat
819
821
  Specify which fields to index with highlighting.
820
822
 
821
823
  ```ruby
822
- class Product < ActiveRecord::Base
824
+ class Product < ApplicationRecord
823
825
  searchkick highlight: [:name]
824
826
  end
825
827
  ```
@@ -872,7 +874,7 @@ product.similar(fields: [:name], where: {size: "12 oz"})
872
874
  ### Geospatial Searches
873
875
 
874
876
  ```ruby
875
- class Restaurant < ActiveRecord::Base
877
+ class Restaurant < ApplicationRecord
876
878
  searchkick locations: [:location]
877
879
 
878
880
  def search_data
@@ -918,7 +920,7 @@ Restaurant.search "wings", boost_by_distance: {location: {origin: {lat: 37, lon:
918
920
  You can also index and search geo shapes.
919
921
 
920
922
  ```ruby
921
- class Restaurant < ActiveRecord::Base
923
+ class Restaurant < ApplicationRecord
922
924
  searchkick geo_shape: {
923
925
  bounds: {tree: "geohash", precision: "1km"}
924
926
  }
@@ -969,11 +971,19 @@ class Dog < Animal
969
971
  end
970
972
  ```
971
973
 
974
+ In your parent model, set:
975
+
976
+ ```ruby
977
+ class Animal < ApplicationRecord
978
+ searchkick inheritance: true
979
+ end
980
+ ```
981
+
972
982
  The parent and child model can both reindex.
973
983
 
974
984
  ```ruby
975
985
  Animal.reindex
976
- Dog.reindex # equivalent
986
+ Dog.reindex # equivalent, all animals reindexed
977
987
  ```
978
988
 
979
989
  And to search, use:
@@ -1076,7 +1086,7 @@ ENV["ELASTICSEARCH_URL"] = "https://es-domain-1234.us-east-1.es.amazonaws.com"
1076
1086
  To use signed request, include in your Gemfile:
1077
1087
 
1078
1088
  ```ruby
1079
- gem 'faraday_middleware-aws-signers-v4'
1089
+ gem 'faraday_middleware-aws-signers-v4', '>= 0.1.9'
1080
1090
  ```
1081
1091
 
1082
1092
  and add to your initializer:
@@ -1170,7 +1180,7 @@ If you run into issues on Windows, check out [this post](https://www.rastating.c
1170
1180
  By default, all string fields are searchable (can be used in `fields` option). Speed up indexing and reduce index size by only making some fields searchable. This disables the `_all` field unless it’s listed.
1171
1181
 
1172
1182
  ```ruby
1173
- class Product < ActiveRecord::Base
1183
+ class Product < ApplicationRecord
1174
1184
  searchkick searchable: [:name]
1175
1185
  end
1176
1186
  ```
@@ -1180,7 +1190,7 @@ end
1180
1190
  By default, all string fields are filterable (can be used in `where` option). Speed up indexing and reduce index size by only making some fields filterable.
1181
1191
 
1182
1192
  ```ruby
1183
- class Product < ActiveRecord::Base
1193
+ class Product < ApplicationRecord
1184
1194
  searchkick filterable: [:brand]
1185
1195
  end
1186
1196
  ```
@@ -1214,7 +1224,7 @@ And use:
1214
1224
  Searchkick.reindex_status(index_name)
1215
1225
  ```
1216
1226
 
1217
- You can also have Searchkick wait for reindexing to complete [master]
1227
+ You can also have Searchkick wait for reindexing to complete
1218
1228
 
1219
1229
  ```ruby
1220
1230
  Searchkick.reindex(async: {wait: true})
@@ -1265,7 +1275,7 @@ Searchkick.redis = ConnectionPool.new { Redis.new }
1265
1275
  And ask your models to queue updates.
1266
1276
 
1267
1277
  ```ruby
1268
- class Product < ActiveRecord::Base
1278
+ class Product < ApplicationRecord
1269
1279
  searchkick callbacks: :queue
1270
1280
  end
1271
1281
  ```
@@ -1289,7 +1299,7 @@ For more tips, check out [Keeping Elasticsearch in Sync](https://www.elastic.co/
1289
1299
  Searchkick supports [Elasticsearch’s routing feature](https://www.elastic.co/blog/customizing-your-document-routing), which can significantly speed up searches.
1290
1300
 
1291
1301
  ```ruby
1292
- class Business < ActiveRecord::Base
1302
+ class Business < ApplicationRecord
1293
1303
  searchkick routing: true
1294
1304
 
1295
1305
  def search_routing
@@ -1309,7 +1319,7 @@ Business.search "ice cream", routing: params[:city_id]
1309
1319
  Reindex a subset of attributes to reduce time spent generating search data and cut down on network traffic.
1310
1320
 
1311
1321
  ```ruby
1312
- class Product < ActiveRecord::Base
1322
+ class Product < ApplicationRecord
1313
1323
  def search_data
1314
1324
  {
1315
1325
  name: name
@@ -1336,7 +1346,7 @@ Product.reindex(:search_prices)
1336
1346
  Split out conversions into a separate method so you can use partial reindexing, and cache conversions to prevent N+1 queries. Be sure to use a centralized cache store like Memcached or Redis.
1337
1347
 
1338
1348
  ```ruby
1339
- class Product < ActiveRecord::Base
1349
+ class Product < ApplicationRecord
1340
1350
  def search_data
1341
1351
  {
1342
1352
  name: name
@@ -1401,7 +1411,7 @@ Searchkick makes it easy to use the Elasticsearch DSL on its own.
1401
1411
  Create a custom mapping:
1402
1412
 
1403
1413
  ```ruby
1404
- class Product < ActiveRecord::Base
1414
+ class Product < ApplicationRecord
1405
1415
  searchkick mappings: {
1406
1416
  product: {
1407
1417
  properties: {
@@ -1416,7 +1426,7 @@ end
1416
1426
  To keep the mappings and settings generated by Searchkick, use:
1417
1427
 
1418
1428
  ```ruby
1419
- class Product < ActiveRecord::Base
1429
+ class Product < ApplicationRecord
1420
1430
  searchkick merge_mappings: true, mappings: {...}
1421
1431
  end
1422
1432
  ```
@@ -1542,7 +1552,7 @@ Product.search_index.clean_indices
1542
1552
  Use custom settings
1543
1553
 
1544
1554
  ```ruby
1545
- class Product < ActiveRecord::Base
1555
+ class Product < ApplicationRecord
1546
1556
  searchkick settings: {number_of_shards: 3}
1547
1557
  end
1548
1558
  ```
@@ -1550,7 +1560,7 @@ end
1550
1560
  Use a different index name
1551
1561
 
1552
1562
  ```ruby
1553
- class Product < ActiveRecord::Base
1563
+ class Product < ApplicationRecord
1554
1564
  searchkick index_name: "products_v2"
1555
1565
  end
1556
1566
  ```
@@ -1558,7 +1568,7 @@ end
1558
1568
  Use a dynamic index name
1559
1569
 
1560
1570
  ```ruby
1561
- class Product < ActiveRecord::Base
1571
+ class Product < ApplicationRecord
1562
1572
  searchkick index_name: -> { "#{name.tableize}-#{I18n.locale}" }
1563
1573
  end
1564
1574
  ```
@@ -1566,11 +1576,17 @@ end
1566
1576
  Prefix the index name
1567
1577
 
1568
1578
  ```ruby
1569
- class Product < ActiveRecord::Base
1579
+ class Product < ApplicationRecord
1570
1580
  searchkick index_prefix: "datakick"
1571
1581
  end
1572
1582
  ```
1573
1583
 
1584
+ For all models
1585
+
1586
+ ```ruby
1587
+ Searchkick.index_prefix = "datakick"
1588
+ ```
1589
+
1574
1590
  Use a different term for boosting by conversions
1575
1591
 
1576
1592
  ```ruby
@@ -1580,7 +1596,7 @@ Product.search("banana", conversions_term: "organic banana")
1580
1596
  Multiple conversion fields
1581
1597
 
1582
1598
  ```ruby
1583
- class Product < ActiveRecord::Base
1599
+ class Product < ApplicationRecord
1584
1600
  has_many :searches, class_name: "Searchjoy::Search"
1585
1601
 
1586
1602
  # searchkick also supports multiple "conversions" fields
@@ -1636,16 +1652,24 @@ Eager load associations
1636
1652
  Product.search "milk", includes: [:brand, :stores]
1637
1653
  ```
1638
1654
 
1639
- Eager load different associations by model [master]
1655
+ Eager load different associations by model
1640
1656
 
1641
1657
  ```ruby
1642
1658
  Searchkick.search("*", index_name: [Product, Store], model_includes: {Product => [:store], Store => [:product]})
1643
1659
  ```
1644
1660
 
1661
+ Specify default fields to search
1662
+
1663
+ ```ruby
1664
+ class Product < ApplicationRecord
1665
+ searchkick default_fields: [:name]
1666
+ end
1667
+ ```
1668
+
1645
1669
  Turn off special characters
1646
1670
 
1647
1671
  ```ruby
1648
- class Product < ActiveRecord::Base
1672
+ class Product < ApplicationRecord
1649
1673
  # A will not match Ä
1650
1674
  searchkick special_characters: false
1651
1675
  end
@@ -1654,7 +1678,7 @@ end
1654
1678
  Use a different [similarity algorithm](https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules-similarity.html) for scoring
1655
1679
 
1656
1680
  ```ruby
1657
- class Product < ActiveRecord::Base
1681
+ class Product < ApplicationRecord
1658
1682
  searchkick similarity: "classic"
1659
1683
  end
1660
1684
  ```
@@ -1662,7 +1686,7 @@ end
1662
1686
  Change import batch size
1663
1687
 
1664
1688
  ```ruby
1665
- class Product < ActiveRecord::Base
1689
+ class Product < ApplicationRecord
1666
1690
  searchkick batch_size: 200 # defaults to 1000
1667
1691
  end
1668
1692
  ```
@@ -1689,7 +1713,7 @@ Product.search("carrots", request_params: {search_type: "dfs_query_then_fetch"})
1689
1713
  Reindex conditionally
1690
1714
 
1691
1715
  ```ruby
1692
- class Product < ActiveRecord::Base
1716
+ class Product < ApplicationRecord
1693
1717
  searchkick callbacks: false
1694
1718
 
1695
1719
  # add the callbacks manually
@@ -1891,7 +1915,7 @@ Product.search_index.refresh
1891
1915
  Due to the distributed nature of Elasticsearch, you can get incorrect results when the number of documents in the index is low. You can [read more about it here](https://www.elastic.co/blog/understanding-query-then-fetch-vs-dfs-query-then-fetch). To fix this, do:
1892
1916
 
1893
1917
  ```ruby
1894
- class Product < ActiveRecord::Base
1918
+ class Product < ApplicationRecord
1895
1919
  searchkick settings: {number_of_shards: 1}
1896
1920
  end
1897
1921
  ```
@@ -318,10 +318,14 @@ module Searchkick
318
318
  client.indices.analyze(body: {text: text}.merge(options), index: name)["tokens"].map { |t| t["token"] }
319
319
  end
320
320
 
321
- def klass_document_type(klass)
322
- @klass_document_type[klass] ||= begin
321
+ def klass_document_type(klass, ignore_type = false)
322
+ @klass_document_type[[klass, ignore_type]] ||= begin
323
323
  if klass.respond_to?(:document_type)
324
324
  klass.document_type
325
+ elsif !ignore_type && klass.searchkick_klass.searchkick_options[:_type]
326
+ type = klass.searchkick_klass.searchkick_options[:_type]
327
+ type = type.call if type.respond_to?(:call)
328
+ type
325
329
  else
326
330
  klass.model_name.to_s.underscore
327
331
  end
@@ -334,11 +338,11 @@ module Searchkick
334
338
  Searchkick.client
335
339
  end
336
340
 
337
- def document_type(record)
341
+ def document_type(record, ignore_type = false)
338
342
  if record.respond_to?(:search_document_type)
339
343
  record.search_document_type
340
344
  else
341
- klass_document_type(record.class)
345
+ klass_document_type(record.class, ignore_type)
342
346
  end
343
347
  end
344
348
 
@@ -386,6 +390,10 @@ module Searchkick
386
390
  end
387
391
  end
388
392
 
393
+ if !source.key?("type") && record.class.searchkick_klass.searchkick_options[:inheritance]
394
+ source["type"] = document_type(record, true)
395
+ end
396
+
389
397
  cast_big_decimal(source)
390
398
 
391
399
  source
@@ -4,6 +4,8 @@ module Searchkick
4
4
  options = @options
5
5
  language = options[:language]
6
6
  language = language.call if language.respond_to?(:call)
7
+ type = options[:_type] || :_default_
8
+ type = type.call if type.respond_to?(:call)
7
9
 
8
10
  if options[:mappings] && !options[:merge_mappings]
9
11
  settings = options[:settings] || {}
@@ -275,6 +277,10 @@ module Searchkick
275
277
  mapping[field] = shape_options.merge(type: "geo_shape")
276
278
  end
277
279
 
280
+ if options[:inheritance]
281
+ mapping[:type] = keyword_mapping
282
+ end
283
+
278
284
  routing = {}
279
285
  if options[:routing]
280
286
  routing = {required: true}
@@ -313,7 +319,7 @@ module Searchkick
313
319
  multi_field = dynamic_fields["{name}"].merge(fields: dynamic_fields.except("{name}"))
314
320
 
315
321
  mappings = {
316
- _default_: {
322
+ type => {
317
323
  properties: mapping,
318
324
  _routing: routing,
319
325
  # https://gist.github.com/kimchy/2898285
@@ -331,7 +337,7 @@ module Searchkick
331
337
 
332
338
  if below60
333
339
  all_enabled = all && (!options[:searchable] || options[:searchable].to_a.map(&:to_s).include?("_all"))
334
- mappings[:_default_][:_all] = all_enabled ? analyzed_field_options : {enabled: false}
340
+ mappings[type][:_all] = all_enabled ? analyzed_field_options : {enabled: false}
335
341
  end
336
342
 
337
343
  mappings = mappings.deep_merge(options[:mappings] || {})
@@ -1,8 +1,8 @@
1
1
  module Searchkick
2
2
  module Model
3
3
  def searchkick(**options)
4
- unknown_keywords = options.keys - [:_all, :batch_size, :callbacks, :conversions, :default_fields,
5
- :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :language,
4
+ unknown_keywords = options.keys - [:_all, :_type, :batch_size, :callbacks, :conversions, :default_fields,
5
+ :filterable, :geo_shape, :highlight, :ignore_above, :index_name, :index_prefix, :inheritance, :language,
6
6
  :locations, :mappings, :match, :merge_mappings, :routing, :searchable, :settings, :similarity,
7
7
  :special_characters, :stem_conversions, :suggest, :synonyms, :text_end,
8
8
  :text_middle, :text_start, :word, :wordnet, :word_end, :word_middle, :word_start]
@@ -12,6 +12,8 @@ module Searchkick
12
12
 
13
13
  Searchkick.models << self
14
14
 
15
+ options[:_type] ||= -> { searchkick_index.klass_document_type(self, true) } if options[:inheritance]
16
+
15
17
  class_eval do
16
18
  cattr_reader :searchkick_options, :searchkick_klass
17
19
 
@@ -233,7 +233,7 @@ module Searchkick
233
233
  if options[:similar]
234
234
  payload = {
235
235
  more_like_this: {
236
- like_text: term,
236
+ like: term,
237
237
  min_doc_freq: 1,
238
238
  min_term_freq: 1,
239
239
  analyzer: "searchkick_search2"
@@ -307,7 +307,7 @@ module Searchkick
307
307
  exclude_field = field
308
308
 
309
309
  if field == "_all" || field.end_with?(".analyzed")
310
- shared_options[:cutoff_frequency] = 0.001 unless operator == "and" || misspellings == false
310
+ shared_options[:cutoff_frequency] = 0.001 unless operator.to_s == "and" || misspellings == false
311
311
  qs.concat [
312
312
  shared_options.merge(analyzer: "searchkick_search"),
313
313
  shared_options.merge(analyzer: "searchkick_search2")
@@ -449,8 +449,14 @@ module Searchkick
449
449
  # indices_boost
450
450
  set_boost_by_indices(payload)
451
451
 
452
+ # type when inheritance
453
+ where = (options[:where] || {}).dup
454
+ if searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
455
+ where[:type] = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v, true) }
456
+ end
457
+
452
458
  # filters
453
- filters = where_filters(options[:where])
459
+ filters = where_filters(where)
454
460
  set_filters(payload, filters) if filters.any?
455
461
 
456
462
  # aggregations
@@ -466,8 +472,7 @@ module Searchkick
466
472
  payload[:timeout] ||= "#{Searchkick.search_timeout + 1}s"
467
473
 
468
474
  # An empty array will cause only the _id and _type for each hit to be returned
469
- # doc for :select - http://www.elasticsearch.org/guide/reference/api/search/fields/
470
- # doc for :select_v2 - https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
475
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html
471
476
  if options[:select]
472
477
  if options[:select] == []
473
478
  # intuitively [] makes sense to return no fields, but ES by default returns all fields
@@ -481,7 +486,7 @@ module Searchkick
481
486
  end
482
487
 
483
488
  # type
484
- if options[:type] || (klass != searchkick_klass && searchkick_index)
489
+ if !searchkick_options[:inheritance] && (options[:type] || (klass != searchkick_klass && searchkick_index))
485
490
  @type = [options[:type] || klass].flatten.map { |v| searchkick_index.klass_document_type(v) }
486
491
  end
487
492
 
@@ -516,6 +521,8 @@ module Searchkick
516
521
  ["_all"]
517
522
  elsif all && default_match == :phrase
518
523
  ["_all.phrase"]
524
+ elsif term == "*"
525
+ []
519
526
  else
520
527
  raise ArgumentError, "Must specify fields to search"
521
528
  end
@@ -1,3 +1,3 @@
1
1
  module Searchkick
2
- VERSION = "2.3.2"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -72,4 +72,10 @@ class AutocompleteTest < Minitest::Test
72
72
  store_names ["hi@example.org"]
73
73
  assert_search "hi@example.org", ["hi@example.org"], fields: [{name: :exact}]
74
74
  end
75
+
76
+ def test_exact_case
77
+ store_names ["Hello"]
78
+ assert_search "hello", [], fields: [{name: :exact}]
79
+ assert_search "Hello", ["Hello"], fields: [{name: :exact}]
80
+ end
75
81
  end
@@ -9,7 +9,6 @@ class InheritanceTest < Minitest::Test
9
9
  def test_child_reindex
10
10
  store_names ["Max"], Cat
11
11
  assert Dog.reindex
12
- Animal.searchkick_index.refresh
13
12
  assert_equal 1, Animal.search("*").size
14
13
  end
15
14
 
@@ -70,7 +69,7 @@ class InheritanceTest < Minitest::Test
70
69
  store_names ["Bear A"], Cat
71
70
  store_names ["Bear B"], Dog
72
71
  Animal.reindex
73
- assert_equal 1, Dog.search("bear").size
72
+ assert_equal 2, Animal.search("bear").size
74
73
  end
75
74
 
76
75
  # TODO move somewhere better
data/test/match_test.rb CHANGED
@@ -18,6 +18,13 @@ class MatchTest < Minitest::Test
18
18
  assert_search "pepperjack cheese skewers", ["Pepper Jack Cheese Skewers"]
19
19
  end
20
20
 
21
+ def test_operator
22
+ store_names ["fresh", "honey"]
23
+ assert_search "fresh honey", ["fresh", "honey"], {operator: "or"}
24
+ assert_search "fresh honey", [], {operator: "and"}
25
+ assert_search "fresh honey", ["fresh", "honey"], {operator: :or}
26
+ end
27
+
21
28
  # def test_cheese_space_in_query
22
29
  # store_names ["Pepperjack Cheese Skewers"]
23
30
  # assert_search "pepper jack cheese skewers", ["Pepperjack Cheese Skewers"]
@@ -238,6 +245,11 @@ class MatchTest < Minitest::Test
238
245
  assert_search "fresh honey", ["Fresh Honey"], match: :phrase
239
246
  end
240
247
 
248
+ def test_phrase_again
249
+ store_names ["Social entrepreneurs don't have it easy raising capital"]
250
+ assert_search "social entrepreneurs don't have it easy raising capital", ["Social entrepreneurs don't have it easy raising capital"], match: :phrase
251
+ end
252
+
241
253
  def test_phrase_order
242
254
  store_names ["Wheat Bread", "Whole Wheat Bread"]
243
255
  assert_order "wheat bread", ["Wheat Bread", "Whole Wheat Bread"], match: :phrase
data/test/test_helper.rb CHANGED
@@ -505,6 +505,7 @@ end
505
505
  class Animal
506
506
  searchkick \
507
507
  default_fields: elasticsearch_below60? ? nil : [:name],
508
+ inheritance: !elasticsearch_below60?,
508
509
  text_start: [:name],
509
510
  suggest: [:name],
510
511
  index_name: -> { "#{name.tableize}-#{Date.today.year}#{Searchkick.index_suffix}" },
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: 2.3.2
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-09 00:00:00.000000000 Z
11
+ date: 2017-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel