Commit f151d404755236b5532b90cb162f862292c10d55
1 parent
de39f792
Exists in
master
and in
21 other branches
add support for fuzzy transpositions
Showing
3 changed files
with
31 additions
and
2 deletions
Show diff stats
README.md
... | ... | @@ -280,6 +280,13 @@ You can also change the edit distance with: |
280 | 280 | Product.search "zucini", misspellings: {edit_distance: 2} # zucchini |
281 | 281 | ``` |
282 | 282 | |
283 | +A transposition of two letters is considered to be an edit distance of 2. Enable single-letter transpositions while leaving edit distance at 1 with: | |
284 | + | |
285 | +```ruby | |
286 | +Product.search "zuccihni", misspellings: {transpositions: true} # zucchini | |
287 | +``` | |
288 | + | |
289 | + | |
283 | 290 | ### Indexing |
284 | 291 | |
285 | 292 | 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 | ... | ... |