From fe5eeef749d8df860fead6ce411fb479d3aec15a Mon Sep 17 00:00:00 2001 From: Vincent Pelletier <vincent@nexedi.com> Date: Wed, 6 May 2009 11:58:44 +0000 Subject: [PATCH] When doing multiple FullText lookups in the same SearchText expression, merge all lookups into just one SQL fulltext match (per expression block). Add a test. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@26836 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ZSQLCatalog/SearchKey/FullTextKey.py | 18 ++++++++++++++++++ product/ZSQLCatalog/tests/testSQLCatalog.py | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/product/ZSQLCatalog/SearchKey/FullTextKey.py b/product/ZSQLCatalog/SearchKey/FullTextKey.py index 0fd98c7fdb..9664d32e59 100644 --- a/product/ZSQLCatalog/SearchKey/FullTextKey.py +++ b/product/ZSQLCatalog/SearchKey/FullTextKey.py @@ -29,9 +29,11 @@ ############################################################################## from SearchKey import SearchKey +from Products.ZSQLCatalog.Query.SimpleQuery import SimpleQuery from Products.ZSQLCatalog.SearchText import parse from Products.ZSQLCatalog.Interface.ISearchKey import ISearchKey from Interface.Verify import verifyClass +from Products.ZSQLCatalog.SQLCatalog import profiler_decorator class FullTextKey(SearchKey): """ @@ -43,5 +45,21 @@ class FullTextKey(SearchKey): def parseSearchText(self, value, is_column): return parse(value, is_column) + @profiler_decorator + def _buildQuery(self, operator_value_dict, logical_operator, parsed, group): + """ + Special Query builder for FullText queries: merge all values having the + same operator into just one query, to save SQL server from the burden to + do multiple fulltext lookups when one would suit the purpose. + """ + column = self.getColumn() + query_list = [] + append = query_list.append + for comparison_operator, value_list in operator_value_dict.iteritems(): + append(SimpleQuery(search_key=self, + comparison_operator=comparison_operator, + group=group, **{column: ' '.join(value_list)})) + return query_list + verifyClass(ISearchKey, FullTextKey) diff --git a/product/ZSQLCatalog/tests/testSQLCatalog.py b/product/ZSQLCatalog/tests/testSQLCatalog.py index 736645b539..aac426c31b 100644 --- a/product/ZSQLCatalog/tests/testSQLCatalog.py +++ b/product/ZSQLCatalog/tests/testSQLCatalog.py @@ -394,6 +394,18 @@ class TestSQLCatalog(unittest.TestCase): self.assertTrue(self._catalog.isAdvancedSearchText('default:a')) # "default" exists as a column self.assertFalse(self._catalog.isAdvancedSearchText('b:a')) # "b" doesn't exist as a column + def test_FullTextSearchMergesQueries(self): + """ + FullText criterion on the same scope must be merged into one query. + Logical operator is ignored, as fulltext operators are expected instead. + """ + self.catalog(ReferenceQuery(ReferenceQuery(operator='match', fulltext='a b'), operator='and'), + {'fulltext': 'a AND b'}) + self.catalog(ReferenceQuery(ReferenceQuery(operator='match', fulltext='a b'), operator='and'), + {'fulltext': 'a OR b'}) + self.catalog(ReferenceQuery(ReferenceQuery(ReferenceQuery(operator='match', fulltext='a b'), operator='not'), operator='and'), + {'fulltext': 'NOT (a b)'}) + ##return catalog(title=Query(title='a', operator='not')) #return catalog(title={'query': 'a', 'operator': 'not'}) #return catalog(title={'query': ['a', 'b'], 'operator': 'not'}) -- 2.30.9