I'm new in both MongoDB and python, and just trying to play with them.
In my one of the first experiments I've faced with some weird thing.
I have an upsert call like this:
def update_value(big_int_value: int, bool_value: bool):
db["my_db"].update_one({"level_1": {"field_1": big_int_value}},
{"$set": {"level_1.field_2": bool_value}},
upsert=True)
It successfully inserts the document the first time.
But I have really big int values, so they are saved as Long('big_int_value')
in mongo:
{
_id: ObjectId("6515e4196b6f0a16194b0f58"),
level_1: { field_1: Long("1144745341514698845"), field_2: true }
}
So when next time I call this update_one
code again with the same big_int_value, it can't find the already existing document and creates a new one.
I had tried to find the existing records in mongosh and was able to find them only with the following query:
db.my_col.find({"level_1.field_1": Long("1144745341514698845")})
Without explicit Long()
, no results found.
I've tried to find the analogue of some casting or wrapping of int to the Mongo-friendly long value in pymongo, but haven't found.
Of course, I have an alternative to store the value not as number, but as string. But I'm curios to see whether there is a native and elegant way to search for mongo's "Long()" values using python's int.
Any info is highly appreciated!
I've found the reason of the behavior I see in my example.
The problem is in the filter query:
db["my_db"].update_one({"level_1": {"field_1": big_int_value}},
{"$set": {"level_1.field_2": bool_value}},
upsert=True)
This part is wrong:
{"level_1": {"field_1": big_int_value}}
In the documentation here it is said:
To specify an equality condition on a field that is an embedded/nested document, use the query filter document { field: value } where value is the document to match.
So the filter form that used tried to find any results there "level_1" field has a nested document as a value with just one field. But in my structure the nested docs have tro fields.
Changed the query with the right filter form and everything started to work well even without any data convertions:
db["my_db"].update_one({"level_1.field_1": big_int_value},
{"$set": {"level_1.field_2": bool_value}},
upsert=True)