From 3ca024ab7aab6e4bcdf61124c740c4a7cf20456e Mon Sep 17 00:00:00 2001 From: Daniel Reis Date: Wed, 1 Jun 2016 18:15:38 +0100 Subject: [PATCH 1/2] [ADD] base_name_search_improved: friendly and powerful name search --- base_name_search_improved/README.rst | 115 ++++++++++++++++++ base_name_search_improved/__init__.py | 2 + base_name_search_improved/__openerp__.py | 19 +++ base_name_search_improved/images/image0.png | Bin 0 -> 16688 bytes base_name_search_improved/images/image1.png | Bin 0 -> 10897 bytes base_name_search_improved/images/image2.png | Bin 0 -> 15567 bytes base_name_search_improved/models/__init__.py | 2 + base_name_search_improved/models/ir_model.py | 61 ++++++++++ .../static/description/icon.png | Bin 0 -> 9455 bytes base_name_search_improved/tests/__init__.py | 5 + .../tests/test_name_search.py | 44 +++++++ base_name_search_improved/views/ir_model.xml | 25 ++++ 12 files changed, 273 insertions(+) create mode 100644 base_name_search_improved/README.rst create mode 100644 base_name_search_improved/__init__.py create mode 100644 base_name_search_improved/__openerp__.py create mode 100644 base_name_search_improved/images/image0.png create mode 100644 base_name_search_improved/images/image1.png create mode 100644 base_name_search_improved/images/image2.png create mode 100644 base_name_search_improved/models/__init__.py create mode 100644 base_name_search_improved/models/ir_model.py create mode 100644 base_name_search_improved/static/description/icon.png create mode 100644 base_name_search_improved/tests/__init__.py create mode 100644 base_name_search_improved/tests/test_name_search.py create mode 100644 base_name_search_improved/views/ir_model.xml diff --git a/base_name_search_improved/README.rst b/base_name_search_improved/README.rst new file mode 100644 index 000000000..46d91e16d --- /dev/null +++ b/base_name_search_improved/README.rst @@ -0,0 +1,115 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +==================== +Improved Name Search +==================== + +Extends the name search feature to use fuzzy matching methods, and +allowing to search in additional related record attributes. + +The name search is the lookup feature to select a related record. +For example, selecting a Customer on a new Sales order. + +For example, typing "john brown" doesn't match "John M. Brown". +The fuzzy search looks up for record containing all the words, +so "John M. Brown" would be a match. +It also tolerates words in a different order, so searching +for "brown john" would also works. + +.. image:: images/image0.png + +Additionally, an Administrator can configure other fields to also lookup into. +For example, Customers could be additionally searched by City or Phone number. + +.. image:: images/image2.png + +How it works: + +Regular name search is performed, and the additional search logic is only +triggered if no results are found. This way, no significan overhead is added +on searches that would normally yield results. + +But if no results are found, then sdditional search methods are tried until +some results are found. The sepcific methods used are: + +- Try regular search on each of the additional fields +- Try ordered word search on each of the search fields +- Try unordered word search on each of the search fields + + +Installation +============ + +No specific requirements. + + +Configuration +============= + +The fuzzy search is automatically enabled on all Models. +Note that this only affects typing in related fields. +The regular ``search()``, used in the top right search box, is not affected. + +Additional search fields can be configured at Settings > Technical > Database > Models, +using the "Name Search Fields" field. + +.. image:: images/image1.png + + +Usage +===== + +Just type into any related field, such as Customer on a Sale Order. + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/149/8.0 + +.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt +.. branch is "8.0" for example + +Known issues / Roadmap +====================== + +* The list of additional fields to search could benefit from caching, for efficiency. +* This feature could be implemented for regular ``search`` on the ``name`` field. + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Daniel Reis + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/base_name_search_improved/__init__.py b/base_name_search_improved/__init__.py new file mode 100644 index 000000000..a0fdc10fe --- /dev/null +++ b/base_name_search_improved/__init__.py @@ -0,0 +1,2 @@ +# -*- coding: utf-8 -*- +from . import models diff --git a/base_name_search_improved/__openerp__.py b/base_name_search_improved/__openerp__.py new file mode 100644 index 000000000..11df47076 --- /dev/null +++ b/base_name_search_improved/__openerp__.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# © 2016 Daniel Reis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +{ + 'name': 'Improved Name Search', + 'summary': 'Friendlier search when typing in relation fields', + 'version': '8.0.1.0.0', + 'category': 'Uncategorized', + 'website': 'https://odoo-community.org/', + 'author': 'Daniel Reis, Odoo Community Association (OCA)', + 'license': 'AGPL-3', + 'data': [ + 'views/ir_model.xml', + ], + 'installable': True, + 'depends': [ + 'base', + ], +} diff --git a/base_name_search_improved/images/image0.png b/base_name_search_improved/images/image0.png new file mode 100644 index 0000000000000000000000000000000000000000..f6bbf6459feeb20c25174964c62c853c1f9f6c59 GIT binary patch literal 16688 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 literal 0 HcmV?d00001 diff --git a/base_name_search_improved/images/image1.png b/base_name_search_improved/images/image1.png new file mode 100644 index 0000000000000000000000000000000000000000..855dbb1a20d97d980d69126957245452b3165033 GIT binary patch literal 10897 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 literal 0 HcmV?d00001 diff --git a/base_name_search_improved/images/image2.png b/base_name_search_improved/images/image2.png new file mode 100644 index 0000000000000000000000000000000000000000..ef5ecac43885db542b4ad4ffe72a65d621f5bc34 GIT binary patch literal 15567 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ƤFaw{(5#r{qem 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/base_name_search_improved/tests/__init__.py b/base_name_search_improved/tests/__init__.py new file mode 100644 index 000000000..4ea57064e --- /dev/null +++ b/base_name_search_improved/tests/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# © 2016 Daniel Reis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import test_name_search diff --git a/base_name_search_improved/tests/test_name_search.py b/base_name_search_improved/tests/test_name_search.py new file mode 100644 index 000000000..4a016affb --- /dev/null +++ b/base_name_search_improved/tests/test_name_search.py @@ -0,0 +1,44 @@ +# -*- coding: utf-8 -*- +# © 2016 Daniel Reis +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp.tests.common import TransactionCase, at_install, post_install + + +@at_install(False) +@post_install(True) +class NameSearchCase(TransactionCase): + + def setUp(self): + super(NameSearchCase, self).setUp() + phone_field = self.env.ref('base.field_res_partner_phone') + model_partner = self.env.ref('base.model_res_partner') + model_partner.name_search_ids = phone_field + self.Partner = self.env['res.partner'] + self.partner1 = self.Partner.create( + {'name': 'Johann Gambolputty of Ulm', + 'phone': '+351 555 777'}) + self.partner2 = self.Partner.create( + {'name': 'Luigi Verconti', + 'phone': '+351 777 555'}) + + def test_NameSearchSearchWithSpaces(self): + """Name Search Match full string, honoring spaces""" + res = self.Partner.name_search('777 555') + self.assertEqual(res[0][0], self.partner2.id) + + def test_NameSearchOrdered(self): + """Name Search Match by words, honoring order""" + res = self.Partner.name_search('johann ulm') + # res is a list of tuples (id, name) + self.assertEqual(res[0][0], self.partner1.id) + + def test_NameSearchUnordered(self): + """Name Search Math by unordered words""" + res = self.Partner.name_search('ulm gambol') + self.assertEqual(res[0][0], self.partner1.id) + + def test_NameSearchMustMatchAllWords(self): + """Name Search Must Match All Words""" + res = self.Partner.name_search('ulm 555 777') + self.assertFalse(res) diff --git a/base_name_search_improved/views/ir_model.xml b/base_name_search_improved/views/ir_model.xml new file mode 100644 index 000000000..fbc3ff7b7 --- /dev/null +++ b/base_name_search_improved/views/ir_model.xml @@ -0,0 +1,25 @@ + + + + + + + + Add Name Searchable to Models + ir.model + + + + + + + + + + + + From fb20a3741d1c950f4860b71ef11718e439dee67d Mon Sep 17 00:00:00 2001 From: Daniel Reis Date: Thu, 9 Jun 2016 23:57:08 +0100 Subject: [PATCH 2/2] Return all results from the several methods, ordered by best match --- base_name_search_improved/README.rst | 24 +++++---- base_name_search_improved/models/ir_model.py | 53 ++++++++++++------- .../tests/test_name_search.py | 42 +++++++-------- 3 files changed, 70 insertions(+), 49 deletions(-) diff --git a/base_name_search_improved/README.rst b/base_name_search_improved/README.rst index 46d91e16d..07998cbb2 100644 --- a/base_name_search_improved/README.rst +++ b/base_name_search_improved/README.rst @@ -6,17 +6,18 @@ Improved Name Search ==================== -Extends the name search feature to use fuzzy matching methods, and -allowing to search in additional related record attributes. +Extends the name search feature to use additional, more relaxed +matching methods, and to allow searching into configurable additional +record fields. The name search is the lookup feature to select a related record. For example, selecting a Customer on a new Sales order. For example, typing "john brown" doesn't match "John M. Brown". -The fuzzy search looks up for record containing all the words, +The relaxed search also looks up for records containing all the words, so "John M. Brown" would be a match. It also tolerates words in a different order, so searching -for "brown john" would also works. +for "brown john" also works. .. image:: images/image0.png @@ -28,16 +29,19 @@ For example, Customers could be additionally searched by City or Phone number. How it works: Regular name search is performed, and the additional search logic is only -triggered if no results are found. This way, no significan overhead is added -on searches that would normally yield results. +triggered if not enough results are found. +This way, no overhead is added on searches that would normally yield results. -But if no results are found, then sdditional search methods are tried until -some results are found. The sepcific methods used are: +But if not enough results are found, then additional search methods are tried. +The specific methods used are: - Try regular search on each of the additional fields - Try ordered word search on each of the search fields - Try unordered word search on each of the search fields +All results found are presented in that order, +hopefully presenting them in order of relevance. + Installation ============ @@ -74,8 +78,10 @@ Just type into any related field, such as Customer on a Sale Order. Known issues / Roadmap ====================== +* Also use fuzzy search, such as the Levenshtein distance: + https://www.postgresql.org/docs/9.5/static/fuzzystrmatch.html * The list of additional fields to search could benefit from caching, for efficiency. -* This feature could be implemented for regular ``search`` on the ``name`` field. +* This feature could also be implemented for regular ``search`` on the ``name`` field. Bug Tracker diff --git a/base_name_search_improved/models/ir_model.py b/base_name_search_improved/models/ir_model.py index 14a8ba9d2..66b00b3ea 100644 --- a/base_name_search_improved/models/ir_model.py +++ b/base_name_search_improved/models/ir_model.py @@ -4,6 +4,29 @@ from openerp import models, fields, api from openerp import SUPERUSER_ID +from openerp import tools + + +# Extended name search is only used on some operators +ALLOWED_OPS = set(['ilike', 'like']) + + +@tools.ormcache(skiparg=0) +def _get_rec_names(self): + model = self.env['ir.model'].search( + [('model', '=', str(self._model))]) + rec_name = [self._rec_name] or [] + other_names = model.name_search_ids.mapped('name') + return rec_name + other_names + + +def _extend_name_results(self, domain, results, limit): + result_count = len(results) + if result_count < limit: + domain += [('id', 'not in', [x[0] for x in results])] + recs = self.search(domain, limit=limit - result_count) + results.extend(recs.name_get()) + return results class ModelExtended(models.Model): @@ -20,35 +43,27 @@ class ModelExtended(models.Model): @api.model def name_search(self, name='', args=None, operator='ilike', limit=100): - # Regular name search + # Perform standard name search res = name_search.origin( self, name=name, args=args, operator=operator, limit=limit) - - allowed_ops = ['ilike', 'like', '='] - if not res and operator in allowed_ops and self._rec_name: + enabled = self.env.context.get('name_search_extended', True) + # Perform extended name search + if enabled and operator in ALLOWED_OPS: # Support a list of fields to search on - model = self.env['ir.model'].search( - [('model', '=', str(self._model))]) - other_names = model.name_search_ids.mapped('name') + all_names = _get_rec_names(self) # Try regular search on each additional search field - for rec_name in other_names: + for rec_name in all_names[1:]: domain = [(rec_name, operator, name)] - recs = self.search(domain, limit=limit) - if recs: - return recs.name_get() + res = _extend_name_results(self, domain, res, limit) # Try ordered word search on each of the search fields - for rec_name in [self._rec_name] + other_names: + for rec_name in all_names: domain = [(rec_name, operator, name.replace(' ', '%'))] - recs = self.search(domain, limit=limit) - if recs: - return recs.name_get() + res = _extend_name_results(self, domain, res, limit) # Try unordered word search on each of the search fields - for rec_name in [self._rec_name] + other_names: + for rec_name in all_names: domain = [(rec_name, operator, x) for x in name.split() if x] - recs = self.search(domain, limit=limit) - if recs: - return recs.name_get() + res = _extend_name_results(self, domain, res, limit) return res return name_search diff --git a/base_name_search_improved/tests/test_name_search.py b/base_name_search_improved/tests/test_name_search.py index 4a016affb..408db3eb5 100644 --- a/base_name_search_improved/tests/test_name_search.py +++ b/base_name_search_improved/tests/test_name_search.py @@ -16,29 +16,29 @@ class NameSearchCase(TransactionCase): model_partner.name_search_ids = phone_field self.Partner = self.env['res.partner'] self.partner1 = self.Partner.create( - {'name': 'Johann Gambolputty of Ulm', - 'phone': '+351 555 777'}) - self.partner2 = self.Partner.create( {'name': 'Luigi Verconti', - 'phone': '+351 777 555'}) - - def test_NameSearchSearchWithSpaces(self): - """Name Search Match full string, honoring spaces""" - res = self.Partner.name_search('777 555') - self.assertEqual(res[0][0], self.partner2.id) - - def test_NameSearchOrdered(self): - """Name Search Match by words, honoring order""" - res = self.Partner.name_search('johann ulm') - # res is a list of tuples (id, name) - self.assertEqual(res[0][0], self.partner1.id) - - def test_NameSearchUnordered(self): - """Name Search Math by unordered words""" - res = self.Partner.name_search('ulm gambol') - self.assertEqual(res[0][0], self.partner1.id) + 'phone': '+351 555 777 333'}) + self.partner2 = self.Partner.create( + {'name': 'Ken Shabby', + 'phone': '+351 555 333 777'}) + self.partner3 = self.Partner.create( + {'name': 'Johann Gambolputty of Ulm', + 'phone': '+351 777 333 555'}) + + def test_RelevanceOrderedResults(self): + """Return results ordered by relevance""" + res = self.Partner.name_search('555 777') + self.assertEqual( + res[0][0], self.partner1.id, + 'Match full string honoring spaces') + self.assertEqual( + res[1][0], self.partner2.id, + 'Match words honoring order of appearance') + self.assertEqual( + res[2][0], self.partner3.id, + 'Match all words, regardless of order of appearance') def test_NameSearchMustMatchAllWords(self): - """Name Search Must Match All Words""" + """Must Match All Words""" res = self.Partner.name_search('ulm 555 777') self.assertFalse(res)