diff --git a/CHANGES.rst b/CHANGES.rst index 6e8e5c6c..41b84850 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,7 +3,7 @@ Changelog 6.1 (unreleased) ---------------- - +- Improve performance of simple ``not`` queries on large catalogs. - Fix case where multiple indexes with similar name seperated by ``_`` were interpreted as options. (`#78 `_) - Fix reversed sorting by multiple index by forcing the ``_sort_iterate_resultset`` diff --git a/src/Products/PluginIndexes/unindex.py b/src/Products/PluginIndexes/unindex.py index 2b616271..9110bb0a 100644 --- a/src/Products/PluginIndexes/unindex.py +++ b/src/Products/PluginIndexes/unindex.py @@ -479,15 +479,6 @@ def query_index(self, record, resultset=None): return cached - if not record.keys and not_parm: - # convert into indexed format - not_parm = list(map(self._convert, not_parm)) - # we have only a 'not' query - record.keys = [k for k in index.keys() if k not in not_parm] - else: - # convert query arguments into indexed format - record.keys = list(map(self._convert, record.keys)) - # Range parameter range_parm = record.get('range', None) if range_parm: @@ -503,6 +494,21 @@ def query_index(self, record, resultset=None): opr = record.usage.lower().split(':') opr, opr_args = opr[0], opr[1:] + # not query + if not record.keys and not_parm: + # convert into indexed format + not_parm = list(map(self._convert, not_parm)) + # we have only a 'not' query + # shortcut/optimization if we have no 'opr' (i.e. no range) + if resultset is not None and opr is None: + i_not_parm = self._apply_not(not_parm, resultset) + if i_not_parm: + return difference(resultset, i_not_parm) + record.keys = [k for k in index.keys() if k not in not_parm] + else: + # convert query arguments into indexed format + record.keys = list(map(self._convert, record.keys)) + if opr == 'range': # range search if 'min' in opr_args: lo = min(record.keys)