From 07290bfe8df0092ccc99281072ffa7ce0e82474b Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Tue, 15 Feb 2022 08:24:53 +0000 Subject: [PATCH] [FIX] website: disable fuzzy search if search term contains numbers Since [1] when fuzzy search was introduced, fuzzy search was also used when the search term contained numbers. This is a problem for companies where the shop search is used on references: the fuzzy search does not match against the whole database and therefore the exact match might not be found. After this commit the exact search is used whenever the search term is made of 80% of numbers or more - because it is very likely to be a reference or an identifier. [1]: https://github.com/odoo/odoo/commit/7559626c54e34b41e1549e28276a650accec6986 opw-2715647 closes odoo/odoo#84943 X-original-commit: 7b44907c322a7b78ef4a5cb46627df4f72b21240 Signed-off-by: Romain Derie (rde) --- addons/website/models/website.py | 3 ++- addons/website/tests/test_fuzzy.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 017993755a1..c4fc144f33e 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -1587,7 +1587,8 @@ class Website(models.Model): :return: term on which a search can be performed instead of the initial search """ - if len(search) < 4 or ' ' in search: + # No fuzzy search for less that 4 characters, multi-words nor 80%+ numbers. + if len(search) < 4 or ' ' in search or len(re.findall(r'\d', search)) / len(search) >= 0.8: return search search = search.lower() words = set() diff --git a/addons/website/tests/test_fuzzy.py b/addons/website/tests/test_fuzzy.py index 48827fa304c..8655e25ae2a 100644 --- a/addons/website/tests/test_fuzzy.py +++ b/addons/website/tests/test_fuzzy.py @@ -222,3 +222,26 @@ class TestAutoComplete(TransactionCase): for result in suggestions['results']: self._check_highlight("many", result['name']) self._check_highlight("many", result['description']) + + def test_07_no_fuzzy_for_mostly_number(self): + """ Ensures exact match is used when search contains mostly numbers. """ + self._create_page('Product P7935432254U7 page', 'Product P7935432254U7', '/numberpage') + suggestions = self._autocomplete("54321") + self.assertEqual(0, suggestions['results_count'], "Test data contains no exact match") + suggestions = self._autocomplete("54322") + self.assertEqual(1, suggestions['results_count'], "Test data contains one exact match") + suggestions = self._autocomplete("P79355") + self.assertEqual(0, suggestions['results_count'], "Test data contains no exact match") + suggestions = self._autocomplete("P79354") + self.assertEqual(1, suggestions['results_count'], "Test data contains one exact match") + self.assertFalse(suggestions['fuzzy_search'], "Expects an exact match") + suggestions = self._autocomplete("produkt") + self.assertEqual(1, suggestions['results_count'], "Test data contains one fuzzy match") + self.assertTrue(suggestions['fuzzy_search'], "Expects a fuzzy match") + + def test_08_fuzzy_classic_numbers(self): + """ Ensures fuzzy match is used when search contains a few numbers. """ + self._create_page('iPhone 6', 'iPhone6', '/iphone6') + suggestions = self._autocomplete("iphone7") + self.assertEqual(1, suggestions['results_count'], "Test data contains one fuzzy match") + self.assertTrue(suggestions['fuzzy_search'], "Expects an fuzzy match")