Home > Software engineering >  PyMongo: querying using json with a list
PyMongo: querying using json with a list

Time:03-03

If I have some json like this:

query = {
   "canonical.operatingSystemFamily": "Linux",
   "canonical.region": "us-east-1"
}

I can pass that directly into find and it works:

self._db_conn[collection_name].find(query)

I want to do the same, but with lists, e.g.:

query = {
    "canonical.operatingSystemFamily": ["Linux","Windows"],
    "canonical.region": ["us-east-1", "us-east-2"]
}

Is there a way to do that? I know about "$in" but I do not want to have to parse my query data. This is a very simplified example, and there are a lot of fields that may or may not be there. Is there a way to use that json with lists directly?

CodePudding user response:

It's not much of a parser - just checking type.

$ ipython
Python 3.8.10 (default, May  4 2021, 00:00:00) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: query = {
   ...:     "canonical.operatingSystemFamily": ["Linux","Windows"],
   ...:     "canonical.region": ["us-east-1", "us-east-2"]
   ...: }

In [2]: for k,v in query.items():
   ...:     if type(v)==list:
   ...:         query[k]={"$in": v}
   ...: 

In [3]: query
Out[3]: 
{'canonical.operatingSystemFamily': {'$in': ['Linux', 'Windows']},
 'canonical.region': {'$in': ['us-east-1', 'us-east-2']}}

If you wanted, you could define a function to transform query when a list is present.

from copy import deepcopy
def query_lfixer(query, copy=True):
    if copy:
        query = deepcopy(query)
    for k, v in query.items():
        if type(v)==list:
            query[k] = {"$in": v}
    return query

And then you could use it like:

self._db_conn[collection_name].find(query_lfixer(query))

Or you could transform query in any number of other ways too.

  • Related