Commit 336bef7d5b27b91d79a6e00bb8fa31baf4f99048

Authored by Andrew Kane
2 parents de39f792 2abfec4f

Merge branch 'meetrajesh-master'

CHANGELOG.md
  1 +## 0.9.1 [unreleased]
  2 +
  3 +- Added `transpositions` option to misspellings
  4 +
1 5 ## 0.9.0
2 6  
3 7 - Much better performance for where queries if no facets
... ...
README.md
... ... @@ -268,18 +268,28 @@ end
268 268  
269 269 ### Misspellings
270 270  
271   -By default, Searchkick handles misspelled queries by returning results with an [edit distance](http://en.wikipedia.org/wiki/Levenshtein_distance) of one. To turn off this feature, use:
  271 +By default, Searchkick handles misspelled queries by returning results with an [edit distance](http://en.wikipedia.org/wiki/Levenshtein_distance) of one.
  272 +
  273 +You can change this with:
  274 +
  275 +```ruby
  276 +Product.search "zucini", misspellings: {edit_distance: 2} # zucchini
  277 +```
  278 +
  279 +Or turn off misspellings with:
272 280  
273 281 ```ruby
274 282 Product.search "zuchini", misspellings: false # no zucchini
275 283 ```
276 284  
277   -You can also change the edit distance with:
  285 +Swapping two letters counts as two edits. To count the [transposition of two adjacent characters as a single edit](https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance), use: [master]
278 286  
279 287 ```ruby
280   -Product.search "zucini", misspellings: {edit_distance: 2} # zucchini
  288 +Product.search "mikl", misspellings: {transpositions: true} # milk
281 289 ```
282 290  
  291 +This is planned to be the default in Searchkick 1.0.
  292 +
283 293 ### Indexing
284 294  
285 295 Control what data is indexed with the `search_data` method. Call `Product.reindex` after changing this method.
... ...
lib/searchkick/query.rb
... ... @@ -107,9 +107,10 @@ module Searchkick
107 107 misspellings = options.key?(:misspellings) ? options[:misspellings] : options[:mispellings] # why not?
108 108 if misspellings != false
109 109 edit_distance = (misspellings.is_a?(Hash) && (misspellings[:edit_distance] || misspellings[:distance])) || 1
  110 + transpositions = (misspellings.is_a?(Hash) && misspellings[:transpositions] == true) ? {fuzzy_transpositions: true} : {}
110 111 qs.concat [
111   - shared_options.merge(fuzziness: edit_distance, max_expansions: 3, analyzer: "searchkick_search"),
112   - shared_options.merge(fuzziness: edit_distance, max_expansions: 3, analyzer: "searchkick_search2")
  112 + shared_options.merge(fuzziness: edit_distance, max_expansions: 3, analyzer: "searchkick_search").merge(transpositions),
  113 + shared_options.merge(fuzziness: edit_distance, max_expansions: 3, analyzer: "searchkick_search2").merge(transpositions)
113 114 ]
114 115 end
115 116 elsif field.end_with?(".exact")
... ...
test/match_test.rb
... ... @@ -112,6 +112,27 @@ class TestMatch < Minitest::Test
112 112 assert_search "zip lock", ["Ziploc"]
113 113 end
114 114  
  115 + def test_misspelling_zucchini_transposition
  116 + store_names ["zucchini"]
  117 + assert_search "zuccihni", [] # doesn't work without transpositions:true option
  118 + assert_search "zuccihni", ["zucchini"], misspellings: {transpositions: true}
  119 + end
  120 +
  121 + def test_misspelling_lasagna
  122 + store_names ["lasagna"]
  123 + assert_search "lasanga", ["lasagna"], misspellings: {transpositions: true}
  124 + assert_search "lasgana", ["lasagna"], misspellings: {transpositions: true}
  125 + assert_search "lasaang", [], misspellings: {transpositions: true} # triple transposition, shouldn't work
  126 + assert_search "lsagana", [], misspellings: {transpositions: true} # triple transposition, shouldn't work
  127 + end
  128 +
  129 + def test_misspelling_lasagna_pasta
  130 + store_names ["lasagna pasta"]
  131 + assert_search "lasanga", ["lasagna pasta"], misspellings: {transpositions: true}
  132 + assert_search "lasanga pasta", ["lasagna pasta"], misspellings: {transpositions: true}
  133 + assert_search "lasanga pasat", ["lasagna pasta"], misspellings: {transpositions: true} # both words misspelled with a transposition should still work
  134 + end
  135 +
115 136 # spaces
116 137  
117 138 def test_spaces_in_field
... ...