Python dictionary for pymongo equivalent expression

I have a python dictionary like this

{'OR': [{'AND': [{'column': 'XXX', 'operator': '=', 'value': u'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]}, {'column': 'YYY', 'operator': '>=', 'value': '3.0'}]} 

Now I want to convert it to something like

 {'$or': [{'$and': [{'XXX': 'M'}, {'YYY': 'N'}]}, {'YYY': {u'$gte': 3.0}}]} 

This is clearly the equivalent pymongo expression that I consider.

the code that I have written so far is as follows:

 FILTMAP = {'>=': '$gte', '<=': '$lte', '>': '$gt', '<': '$lt', "!=":"$ne"} CONJUNCTION_MAP = {"AND":"$and", "OR":"$or"} def gen_mongo_filters_json(filter, supplied_key="") first_key = filters.keys()[0] if first_key == 'OR' or first_key == 'AND': if supplied_key == "": return_dict[CONJUNCTION_MAP[first_key]] = [] else: temp_dict[CONJUNCTION_MAP[first_key]] = [] #return_dict[supplied_key] = temp_dict for i in range (len(filters[first_key])): if supplied_key == "": return_dict[CONJUNCTION_MAP[first_key]].append(gen_mongo_filters_json(filters[first_key][i], first_key)) else: temp_dict[CONJUNCTION_MAP[first_key]].append(gen_mongo_filters_json(filters[first_key][i], first_key)) return_dict[CONJUNCTION_MAP[supplied_key]].append(temp_dict) else: operator = filters['operator'] if operator == "=": ret_dict = {filters['column']:filters['value'] return ret_dict else: operator = FILTMAP[operator] ret_dict = {filters['column']:{operator:filters['value']}} return ret_dict return return_dict 

The result he receives:

  {u'$or': [{u'$and': [{u'Engine': u'MSN'}, {u'Engine': u'Google'}]}, {u'$and': [{u'Engine': u'MSN'}, {u'Engine': u'Google'}]}, {...}, {u'Imps': {u'$gte': 3.0}}]} 

Which is close to a solution, but not accurate. It is great for dictionaries such as

 {'AND': [{'column': 'XXX', 'operator': '=', 'value': 'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]} OR {'column': 'YYY', 'operator': '>', 'value': '1000'} 

Can you tell me the direction?

(the idea is to create a generic one, so I would like to generate the equivalent of any valid python dictionary in the pymongo instruction, the minimum is the last)

+4
source share
2 answers

Your sample code does not run, but given that dict

 {'OR': [{'AND': [{'column': 'XXX', 'operator': '=', 'value': 'M'}, {'column': 'YYY', 'operator': '=', 'value': 'N'}]}, {'column': 'YYY', 'operator': '>=', 'value': '3.0'}]} 

must be converted to

 {'$or': [{'$and': [{'XXX': 'M'}, {'YYY': 'N'}]}, {'YYY': {'$gte': 3.0}}]} 

use something like this:

 FILTMAP = {'>=': '$gte', '<=': '$lte', '>': '$gt', '<': '$lt', "!=":"$ne"} CONJUNCTION_MAP = {"AND":"$and", "OR":"$or"} def convert_column(dic): if not dic['operator'] in FILTMAP: return {dic['column']: dic['value']} else: value = float(dic['value']) if dic['operator'] == "!=" else dic['value'] return {dic['column']: {FILTMAP[dic['operator']]: value}} def convert(dic): for k,v in dic.items(): if isinstance(v, list): if k in CONJUNCTION_MAP: k = CONJUNCTION_MAP[k] return {k: [convert(i) for i in v]} else: return convert_column(dic) 

I do not know if it is important to convert '3.0' to 3.0 . Line

 value = float(dic['value']) if dic['operator'] == "!=" else dic['value'] 

rather hacky, you want to replace it with appropriate logic to handle these cases.

+3
source

Thanks for the answer. I also understood something. here is the full code

 FILTMAP = {'>=': '$gte', '<=': '$lte', '>': '$gt', '<': '$lt', "!=":"$ne"} CONJUNCTION_MAP = {"AND":"$and", "OR":"$or"} def gen_mongo_filters_json(filters, supplied_key=""): return_dict = {} temp_dict = {} first_key = filters.keys()[0] if first_key == 'OR' or first_key == 'AND': if supplied_key == "": return_dict[CONJUNCTION_MAP[first_key]] = [] else: temp_dict[CONJUNCTION_MAP[first_key]] = [] #return_dict[supplied_key] = temp_dict""" for i in range (len(filters[first_key])): if supplied_key == "": return_dict[CONJUNCTION_MAP[first_key]].append(gen_mongo_filters_json(filters[first_key][i], first_key)) else: for i in range (len(filters[first_key])): temp_dict[CONJUNCTION_MAP[first_key]].append(gen_mongo_filters_json(filters[first_key][i], first_key)) return temp_dict else: operator = filters['operator'] if operator == "=": ret_dict = {filters['column']:filters['value']} return ret_dict else: operator = FILTMAP[operator] ret_dict = {filters['column']:{operator:filters['value']}} return ret_dict return return_dict if __name__ == "__main__": print gen_mongo_filters_json({'OR': [{'AND': [{'column': 'XXX', 'operator': '=', 'value': 'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]}, {'AND': [{'column': 'PPP', 'operator': '=', 'value': 'R'}, {'column': 'DDD', 'operator': '=', 'value': 'T'}]}]}) enter code here 

Please let me know your feedback.

I tried it for

 {'column': 'YYY', 'operator': '>', 'value': '1000'} {'AND': [{'column': 'XXX', 'operator': '=', 'value': 'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]} {'OR': [{'AND': [{'column': 'XXX', 'operator': '=', 'value': u'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]}, {'column': 'YYY', 'operator': '>=', 'value': '3.0'}]} {'OR': [{'AND': [{'column': 'XXX', 'operator': '=', 'value': u'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]}, {'AND': [{'column': 'PPP', 'operator': '=', 'value': u'R'}, {'column': 'DDD', 'operator': '=', 'value': 'T'}]}]} 

and here are the exits

 {u'YYY': {u'$gt': u'1000'}} {u'$and': [{u'XXX': u'M'}, {u'XXX': u'N'}]} {u'$or': [{u'$and': [{u'XXX': u'M'}, {u'XXX': u'N'}]}, {u'YYY': {u'$gte': u'3.0'}}]} {u'$or': [{u'$and': [{u'XXX': u'M'}, {u'XXX': u'N'}]}, {u'$and': [{u'PPP': u'R'}, {u'DDD': u'T'}]}]} 

Thanks for the answer. Its nice too. I will try now.

And one more thing, I actually omitted the β€œvalue” in my sample code. I thank you for that. I already have a means to achieve this. Anyway, thanks.

0
source

Source: https://habr.com/ru/post/1437780/


All Articles