Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use conditional statements in Pymongo find method

So I am trying to search through my database to see which documents passed a particular test. The structure of the dictionary is

dict = {
       'test_results':{
                        'test1':1, ## either 0 or 1 depending on failing/passing respectively 
                        'test2':0,
                        ...,
                        'testN':1
        },
       'identifier': ID 
}

So I want to do a search to print all the identifiers of documents that failed test 2.

I tried writing a query such as

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

list(mycol.find({},{
    "_id":0,
    "$expr":{
        "$cond": {
            'if': {"$lt":["$test_results.test2",1]},
            'then': {"ID":"$identifier"}
        }
    }
}))

I expected this to give me the identifiers of the documents where test 2 resulted in 0, however this just gives me the error

FieldPath field names may not start with '$'. Consider using $getField or $setField., full error: {'ok': 0.0, 'errmsg': "FieldPath field names may not start with '$'. Consider using $getField or $setField.", 'code': 16410, 'codeName': 'Location16410'}

I was wondering what did I do wrong with my query/any suggestions to make my search more efficient.

>Solution :

That second parameter to find is a projection, so it must have field names at the top level. You’ve put $expr but you probably wanted ID. So to fix your existing query with the least changes:

list(mycol.find({},{
  "_id": 0,
  "ID": {
    "$cond": {
      "if": { "$lt": ["$test_results.test2", 1] },
      "then": "$identifier",
      "else": None
    }
  }
}))

JS equivalent in Mongo Plaground.

But with that query you get None for those IDs where it passed; which is probably not useful. See the second document in the playground which has test2: 1 so the result has ID: null.

However, you said "give me the identifiers of the documents where test 2 resulted in 0", so that should be part of your find criteria:

list(mycol.find(
  { "test_results.test2": 0 },  # the query
  # the projection
  {
    "_id": 0,
    "ID": "$identifier"
  }
))

As you can see, this is a far simpler query & projection. Mongo Playground

And unless you have negative values which should be treated like 0, check for equality with 0 instead of "less than 1". If you actually need a "less than 1" check, then do:

list(mycol.find(
  { "test_results.test2": {"$lt": 1} },
  # the projection
  {
    "_id": 0,
    "ID": "$identifier"
  }
))
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading