Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python function that takes a json object returns mongodb query object

I need to take a JSON (conditions to filter data), example data:

query = { "and": [
    {
      "field": "model",
      "operator": ">",
      "value": "2005"
    },
    {
      "or": [
        {
          "field": "brand",
          "operator": "=",
          "value": "Mercedes"
        },
        {
          "field": "brand",
          "operator": "=",
          "value": "BMW"
        }
      ]
    }
  ]

and write a function that transforms this JSON as a MongoDB query so I can directly filter the data while reading from MongoDb (I will use this data inside of apache beam ReadFromMongoDB function, as filter object)

so the output should be like:

{'$and': [{'field': 'model', 'operator': '>', 'value': '2005'}, {
 '$or': [
     {'field': 'brand', 'operator': '=', 'value': 'Mercedes'},
     {'field': 'brand', 'operator': '=', 'value': 'BMW'}
    ]
 }]}

( I have a function that transforms each single object into a MongoDB query so don't worry about that)

WHAT I TRIED

As I don't know how nested data will come, I used recursion in my function. But it becomes complicated and output is not as I expected.

def splitToItems(query, items={}):
    if 'and' in query:
        for item in query['and']:
            if 'and' in item or 'or' in item:
                splitToItems(item)
            else:
                if '$and' not in items:
                    items['$and'] = [item]
                   # print(items)
                else:
                    items['$and'].append(item)
                  #  print(items)
                
                
    if 'or' in query:
        for item in query['or']:
            if 'and' in item or 'or' in item:
                return splitToItems(item)
            else:
                if '$or' not in items:
                    items['$or'] = [item]
                  #  print(items)
                else:
                    items['$or'].append(item)
                 #   print(items)
    print(items)

------- 
OUTPUT: 

# '$or' should have been inside of the first array in this case
 
{
'$and': [{'field': 'model', 'operator': '>', 'value': '2005'}],
 '$or': [{'field': 'brand', 'operator': '=', 'value': 'Mercedes'}, {'field': 'brand', 'operator': '=', 'value': 'BMW'}]
}

Any idea on how to improve this function or make this work? Many thanks in advance

like image 934
bdemirka Avatar asked Feb 25 '26 09:02

bdemirka


1 Answers

Hopefully I understood the question right

def splitToItems(query, items={}):
    q = {}
    if 'and' in query:
        l = []
        for item in query['and']:
           l.append(splitToItems(item))
        q["$and"] = l

    if 'or' in query:
        l = []
        for item in query['or']:
           l.append(splitToItems(item))
        q["$or"] = l

    if q:
        return q
    return query

print(splitToItems(query))

Does this solve your problem?

like image 88
Mihai Avatar answered Feb 28 '26 00:02

Mihai



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!