Search code examples
javascriptpythonmongodbpymongo

Mongodb query containing a JS function returning missing ")" error when passed as string in python file


I'm having one database with nested fields. To iterate over nested fields and to find a specific value, I'm having this query, which is working fine in robo3t, but when I put it into python file for using in project. I get error. Query in robo3t is this-

db.collection.find({$where: function() {
    function  deepIterate(obj, value) {
        for (field in obj) {
            if (obj[field] == value){
                return true;
            }
            found = false;
            if ( typeof obj[field] === 'object' ) {
                found = deepIterate(obj[field], value)
                if (found) { return true; }
            }
        }
        return false;
    };
    return deepIterate(this, "10.174.113.7")
}}
)

Passing it in python after converting to string like this -

db.collection.find({"$where" : "function() {"
    "function deepIterate(obj, value) {"
        "for(field in obj) {"
            "if (obj[field] == value ) {"
                "return obj;"
            "};"
           "found = false;"
            "if" "(typeof obj[field] === 'object') {"
                "found" "=" "deepIterate(obj[field], value);"
                "if" "(found)" "{return true};"
            "};"
        "};"
        "return false;"
    "};"
    "return deepIterate(this," + "58:FB:96:16:1D:F0"+ ")"
"}"
})

Errors that I'm getting -

Traceback (most recent call last):
  File "test.py", line 39, in <module>
    for a in collection.find(db_query):
  File "/usr/local/lib/python3.8/dist-packages/pymongo/cursor.py", line 1238, in next
    if len(self.__data) or self._refresh():
  File "/usr/local/lib/python3.8/dist-packages/pymongo/cursor.py", line 1155, in _refresh
    self.__send_message(q)
  File "/usr/local/lib/python3.8/dist-packages/pymongo/cursor.py", line 1044, in __send_message
    response = client._run_operation(
  File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 1424, in _run_operation
    return self._retryable_read(
  File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 1525, in _retryable_read
    return func(session, server, sock_info, secondary_ok)
  File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 1420, in _cmd
    return server.run_operation(
  File "/usr/local/lib/python3.8/dist-packages/pymongo/server.py", line 130, in run_operation
    _check_command_response(first, sock_info.max_wire_version)
  File "/usr/local/lib/python3.8/dist-packages/pymongo/helpers.py", line 167, in _check_command_response
    raise OperationFailure(errmsg, code, response, max_wire_version)
pymongo.errors.OperationFailure: SyntaxError: missing ) in parenthetical @:1:235
, full error: {'ok': 0.0, 'errmsg': 'SyntaxError: missing ) in parenthetical @:1:235\n', 'code': 139, 'codeName': 'JSInterpreterFailure'}

Please help!!


Solution

  • Unless the javascript interpreter makes special accomodations for things separated by colons, you need to quote the thing you're searching for:

    v = '58:FB:96:16:1D:F0'
    
    db.collection.find({"$where" : "function() {"
        "function deepIterate(obj, value) {"
            "for(field in obj) {"
                "if (obj[field] == value ) {"
                    "return obj;"
                "};"
               "found = false;"
                "if" "(typeof obj[field] === 'object') {"
                    "found" "=" "deepIterate(obj[field], value);"
                    "if" "(found)" "{return true};"
                "};"
            "};"
            "return false;"
        "};"
        "return deepIterate(this, '" + v + "')"
    "}"
    })