Словарь Python для эквивалентного оператора pymongo


У меня есть такой словарь python

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

Теперь я хочу преобразовать его в нечто вроде

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

, которое, очевидно, эквивалентно заявлению, pymongo я считаю.

Код, который я написал до сих пор, выглядит так:
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

Выходные данные, которые он генерирует:

 {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}}]}

, что близко к решению, но не является точным. Это прекрасно работает для таких словарей, как

{'AND': [{'column': 'XXX', 'operator': '=', 'value': 'M'}, {'column': 'XXX', 'operator': '=', 'value': 'N'}]}

OR

{'column': 'YYY', 'operator': '>', 'value': '1000'}
Можете ли вы указать мне направление?

(идея состоит в том, чтобы создать общий один. Итак, я хотел бы сгенерировать эквивалент любого допустимого словаря python в оператор pymongo. минимум-это последний)

2   4   2012-10-04 14:56:52

2 ответа:

Ваш пример кода не выполняется, но учитывая, что дикт

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

Должно быть преобразовано в

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

Используйте что-то вроде этого:

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)
Я не знаю, важно ли преобразовать '3.0' в 3.0. Линия
value = float(dic['value']) if dic['operator'] == "!=" else dic['value']

Довольно банально, вы хотите заменить его какой-то соответствующей логикой, чтобы справиться с этими случаями.

Спасибо за ответ. Я тоже кое-что выяснил. вот полный код

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

Пожалуйста, дайте мне знать ваши отзывы

Я попробовал его для

{'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'}]}]}

И вот выходы

{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'}]}]}

Спасибо за ответ. Это тоже приятно. Я попробую сделать это сейчас.

И еще одна вещь, я фактически опустил рассмотрение "значения" в моем примере кода. Я благодарен Вам за то, что вы указали на это. У меня уже есть средство для достижения этого. Все равно спасибо.