Skip to content

Commit

Permalink
stringify query mask for future db storage
Browse files Browse the repository at this point in the history
  • Loading branch information
esedor committed Oct 9, 2012
1 parent eeed459 commit bc2f2d7
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 39 deletions.
25 changes: 8 additions & 17 deletions README.md
Expand Up @@ -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.)
Expand Down Expand Up @@ -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:
Expand All @@ -251,24 +252,14 @@ Verbose Sample:
{
"queriesCovered": [
{
"q": {
"classes": "<classes>",
"name": "<name>",
"level": "<level>"
},
"queryMask": "{'q': {'classes': '<classes>' , 'name': '<name>' , 'level': '<level>' }}",
"avgTimeMillis": 210,
"queryCount": 6919,
"totalTimeMillis": 1454932
},
{
"q": {
"classes": "<classes>",
"name": "<name>"
},
"queryMask": "{'q': {'classes': '<classes>', 'name': '<name>' }, 's': {'level': <sort-order>}}",
"avgTimeMillis": 268,
"s": {
"level": "<level>"
},
"queryCount": 6918,
"totalTimeMillis": 1860861
}
Expand Down
53 changes: 31 additions & 22 deletions dex/dex.py
Expand Up @@ -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,
Expand Down Expand Up @@ -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

############################################################################
Expand Down Expand Up @@ -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

############################################################################
Expand All @@ -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 += "<sort-order>"

if sfirst:
return "{" + qmask + "}}"
else:
return "{" + qmask + "}, " + smask + "}}"


0 comments on commit bc2f2d7

Please sign in to comment.