From bc2f2d73550e3a72ef0d0661a9731f2ac3a1a985 Mon Sep 17 00:00:00 2001 From: Eric Sedor Date: Mon, 8 Oct 2012 17:50:20 -0700 Subject: [PATCH] stringify query mask for future db storage --- README.md | 25 ++++++++----------------- dex/dex.py | 53 +++++++++++++++++++++++++++++++---------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index d323c70..1d39a8f 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ index, if one is not found. Dex recommends partially-ordered indexes according to a rule of thumb: Your index field order should first answer: + 1) Equivalent value checks 2) Sort clauses 3) Range value checks ($in, $nin, $lt/gt, $lte/gte, etc.) @@ -229,13 +230,13 @@ prompted the recommendation. the MongoDB shell. * queriesCovered - An array of unique query patterns addressed by the recommendation, and statistics for each. - * queriesCovered.q - The query pattern, with values replaced by a mask. - * queriesCovered.s - The query's sort component, if any. - * queriesCovered.queryCount - The total number of queries matching the query + * queryMask - The query pattern, with values masked (q for query component, + s for sort component) + * queryCount - The total number of queries matching the query pattern. - * queriesCovered.avgTimeMillis - The average time each query with the pattern + * avgTimeMillis - The average time each query with the pattern takes. - * queriesCovered.totalTimeMillis - The sum amount of time consumed by all of + * totalTimeMillis - The sum amount of time consumed by all of the queries of that pattern. Verbose Sample: @@ -251,24 +252,14 @@ Verbose Sample: { "queriesCovered": [ { - "q": { - "classes": "", - "name": "", - "level": "" - }, + "queryMask": "{'q': {'classes': '' , 'name': '' , 'level': '' }}", "avgTimeMillis": 210, "queryCount": 6919, "totalTimeMillis": 1454932 }, { - "q": { - "classes": "", - "name": "" - }, + "queryMask": "{'q': {'classes': '', 'name': '' }, 's': {'level': }}", "avgTimeMillis": 268, - "s": { - "level": "" - }, "queryCount": 6918, "totalTimeMillis": 1860861 } diff --git a/dex/dex.py b/dex/dex.py index 2fe63e8..7259e8d 100755 --- a/dex/dex.py +++ b/dex/dex.py @@ -403,7 +403,7 @@ def _generate_query_report(self, db_uri, raw_query, db_name, collection_name): """Generates a comprehensive report on the raw query""" index_analysis = None recommendation = None - parsed_query = self._mask_query(raw_query) + parsed_query = raw_query namespace = raw_query['ns'] index_cache_entry = self._ensure_index_cache(db_uri, @@ -868,14 +868,8 @@ def _get_existing_query(self, report, queryAnalysis): """Returns the query in report that matches queryAnalysis""" mask = self._get_query_mask(queryAnalysis) for query in report['queriesCovered']: - if mask['q'] == query['q']: - if mask.has_key('s'): - if query.has_key('s'): - if query['s'] == mask['s']: - return query - else: - if not query.has_key('s'): - return query + if mask == query['queryMask']: + return query return None ############################################################################ @@ -914,10 +908,10 @@ def _get_initial_report(self, report): def _get_initial_query(self, report): """Returns a new query query document from the report""" initial_millis = int(report['parsed']['millis']) - query = self._get_query_mask(report['queryAnalysis']) - query['totalTimeMillis'] = initial_millis - query['queryCount'] = 1 - query['avgTimeMillis'] = initial_millis + query = { 'queryMask' : self._get_query_mask(report['queryAnalysis']), + 'totalTimeMillis': initial_millis, + 'queryCount' : 1, + 'avgTimeMillis': initial_millis } return query ############################################################################ @@ -932,15 +926,30 @@ def _get_abbreviated_report(self, report): ############################################################################ def _get_query_mask(self, queryAnalysis): """Converts a queryAnalysis to a query mask""" - q = {} - s = {} - mask = { 'q': q } + qmask = "'q': {" + smask = "'s': {" + qfirst = True + sfirst = True for field in queryAnalysis['analyzedFields']: if field['fieldType'] is not SORT_TYPE: - q[field['fieldName']] = '<' + field['fieldName'] + '>' + if qfirst: + qmask += "'" + field['fieldName'] + "': " + qfirst = False + else: + qmask += ", '" + field['fieldName'] + "': " + qmask += "'<" + field['fieldName'] + ">' " + else: - s[field['fieldName']] = '<' + field['fieldName'] + '>' - mask = { 'q': q } - if len(s.keys()) is not 0: - mask['s'] = s - return mask + if sfirst: + smask += "'" + field['fieldName'] + "': " + sfirst = False + else: + smask += ", '" + field['fieldName'] + "': " + smask += "" + + if sfirst: + return "{" + qmask + "}}" + else: + return "{" + qmask + "}, " + smask + "}}" + +