Last active
December 23, 2015 07:59
-
-
Save sheki/6604949 to your computer and use it in GitHub Desktop.
The algorithm to flatten MongoQueries so that they can be represented by a single query key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Converts a Query JSON into a flat key. | |
| #{ | |
| # "where": { | |
| # "activityDistance": { | |
| # "$gte": 2.5 | |
| # }, | |
| # "accumulatedTotalDistance": { | |
| # "$lte": 10695 | |
| # }, | |
| # " | |
| # "order": "-createdAt", | |
| #} | |
| # to a flat key like : | |
| # "{\"$OR\": [{\"_acl\": {\"$exists\": \"\"}}, {\"_acl.*.r\": \"\"}]}" | |
| ARRAY_QUERY_SET = Set(["$in", "$nin", "$box", "$nearSphere", "$all", "$within"]) | |
| class SimpleQueryAST: | |
| """ represent a query ast in a simplified manne """ | |
| def __init__(self, json): | |
| self._simple_where_keys = [] # simple where clauses | |
| self._where_in_keys = [] # keys with where in clause | |
| self._other_keys = [] # ignored for now. | |
| self._or_keys = [] # or keys | |
| self.collection_name = "" | |
| self.app_key = "" | |
| self.__flatten_json(json) | |
| self._where_in_keys.sort() | |
| self._simple_where_keys.sort() | |
| self._other_keys.sort() | |
| self._or_keys.sort() | |
| def __remove_values(self,json_obj): | |
| result = {} | |
| for k,v in json_obj.items(): | |
| if type(v) == dict: | |
| result[k] = self.__remove_values(v) | |
| elif k == "$or": | |
| assert type(v) == list | |
| temp = [] | |
| for item in v: | |
| temp.append(self.__remove_values(item)) | |
| result["$OR"] = temp | |
| elif k in ARRAY_QUERY_SET: | |
| return "$ARRAY_QUERY" | |
| elif type(v) == str or type(v) == int or type(v) == float or isinstance(v, datetime.datetime) or type(v) == bool or type(v) == unicode or v == None: | |
| result[k] = "" | |
| else: | |
| sys.stderr.write("COULD NOT UNDERSTAND THE OBJECT %s\n".format(str(json_obj))) | |
| sys.exit(1) | |
| return result | |
| def __flatten_json(self, json_obj): | |
| self.collection_name = json_obj[COLLECTION_NAME_KEY] | |
| self.answer = self.__remove_values(json_obj[WHERE_KEY]) | |
| if ORDER_KEY in json_obj: | |
| self.answer['ORDER'] = sorted(json_obj[ORDER_KEY]) | |
| self.answer_str = json.dumps(self.answer, sort_keys = True) | |
| if __name__ == "__main__": | |
| query = SimpleQueryAST({"where":{"_id":{"$in":["1","2"]},"_rperm":{"$in":["*",null,"xyzzy","spoon"]}}) # just a sample query |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment