Commit 336bef7d5b27b91d79a6e00bb8fa31baf4f99048
Exists in
master
and in
21 other branches
Merge branch 'meetrajesh-master'
Showing
4 changed files
with
41 additions
and
5 deletions
Show diff stats
CHANGELOG.md
README.md
@@ -268,18 +268,28 @@ end | @@ -268,18 +268,28 @@ end | ||
268 | 268 | ||
269 | ### Misspellings | 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 | ```ruby | 281 | ```ruby |
274 | Product.search "zuchini", misspellings: false # no zucchini | 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 | ```ruby | 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 | ### Indexing | 293 | ### Indexing |
284 | 294 | ||
285 | Control what data is indexed with the `search_data` method. Call `Product.reindex` after changing this method. | 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,9 +107,10 @@ module Searchkick | ||
107 | misspellings = options.key?(:misspellings) ? options[:misspellings] : options[:mispellings] # why not? | 107 | misspellings = options.key?(:misspellings) ? options[:misspellings] : options[:mispellings] # why not? |
108 | if misspellings != false | 108 | if misspellings != false |
109 | edit_distance = (misspellings.is_a?(Hash) && (misspellings[:edit_distance] || misspellings[:distance])) || 1 | 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 | qs.concat [ | 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 | end | 115 | end |
115 | elsif field.end_with?(".exact") | 116 | elsif field.end_with?(".exact") |
test/match_test.rb
@@ -112,6 +112,27 @@ class TestMatch < Minitest::Test | @@ -112,6 +112,27 @@ class TestMatch < Minitest::Test | ||
112 | assert_search "zip lock", ["Ziploc"] | 112 | assert_search "zip lock", ["Ziploc"] |
113 | end | 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 | # spaces | 136 | # spaces |
116 | 137 | ||
117 | def test_spaces_in_field | 138 | def test_spaces_in_field |