[Patchew-devel] [PATCH v2 03/10] search: introduce _make_filter_subquery

Paolo Bonzini pbonzini at redhat.com
Fri Sep 28 14:45:30 UTC 2018


Django is pretty inefficient when related fields are introduced, and
sometimes incorrect results are produced (for example "success:testing
-failure:testing" does not work if Results are queried through
result__* fields).  A more efficient (and working) way to achieve the
same is to use "IN" with subqueries.  Convert is:applied, is:tested
and is:obsoleted/is:old to use subqueries.

Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
 api/search.py | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/api/search.py b/api/search.py
index 17424c3..b33aa1b 100644
--- a/api/search.py
+++ b/api/search.py
@@ -8,7 +8,7 @@
 # This work is licensed under the MIT License.  Please see the LICENSE file or
 # http://opensource.org/licenses/MIT.
 
-from .models import Message, Result
+from .models import Message, MessageProperty, Result
 from django.db.models import Q
 
 class InvalidSearchTerm(Exception):
@@ -124,6 +124,10 @@ Search text keyword in the email message. Example:
     regression
 
 """
+    def _make_filter_subquery(self, model, q):
+        message_ids = model.objects.filter(q).values('message_id')
+        return Q(id__in=message_ids)
+
     def _process_term(self, query, term, neg=False):
         """ Return a Q object that will be applied to the query """
         def as_keywords(t):
@@ -163,19 +167,15 @@ Search text keyword in the email message. Example:
             elif cond == "pull":
                 q = Q(subject__contains='[PULL') | Q(subject__contains='[GIT PULL')
             elif cond == "reviewed":
-                q = Q(properties__name="reviewed",
-                      properties__value=True)
+                q = self._make_filter_subquery(MessageProperty, Q(name="reviewed", value=True))
             elif cond in ("obsoleted", "old"):
-                q = Q(properties__name="obsoleted-by",
-                      properties__value__isnull=False) & \
-                    ~Q(properties__name="obsoleted-by",
-                      properties__value__iexact='')
+                q = self._make_filter_subquery(MessageProperty,
+                                               Q(name="obsoleted-by", value__isnull=False) &
+                                               ~Q(name="obsoleted-by", value__iexact=''))
             elif cond == "applied":
-                q = Q(results__name="git",
-                      results__status=Result.SUCCESS)
+                q = self._make_filter_subquery(MessageResult, Q(name="git", status=Result.SUCCESS))
             elif cond == "tested":
-                q = Q(properties__name="testing.done",
-                      properties__value=True)
+                q = self._make_filter_subquery(MessageProperty, Q(name="testing.done", value=True))
             elif cond == "merged":
                 q = Q(is_merged=True)
             else:
-- 
2.17.1





More information about the Patchew-devel mailing list