I have a Mongodb Collection in which a decimal amount is stored as a string.
I would like to be able to query treating that field as a number.
Is that possible without elaborate code? I would expect to be able to do. tonumber(field):{$gt:100}.
But I can't find anything.
Related
I have stored crypto account addresses in mongodb, and want to retrieve documents using the addresses. One example look like this "0x754B2f9797b096f417a24686c4B368F508...". My schema specify the addresses are string, and thus, the addresses are stored in mongodb in string and look as the above example. I can retrieve document as expected in mongosh (shell). However, I cannot retrieve any document even if I pass literal string in the filter with mongoose (using find, findOne, and so on). The only way to retrive documents is to not pass any filter. I guess mongoose interprets the value as number and thus convert it before pass to mongodb.
How can I fix the problem?
Thanks.
I have a MongoDB Collection build like this :
When I try to filter by ID, I got inconsistent results. For exemple, when I try to get the first entry, by typing in filter query :
{_id:209383449381830657}
I got no result found.
But if I type for exemple the third, It work correctly.
{_id:191312485326913536}
I searched if it's due to too large int but no, all _id value are Int64 and it's the same code that generate all entries.
I really don't know why I got this result and that why I am asking here.
EDIT:
All entries have same type.
No limit are set in query.
If I type {_id:{"$gte":209383449381830657}} it found the entry, but don't if I type {_id:{"$eq":209383449381830657}}
MongoDB Compass uses mongo's node.js driver.
Both 209383449381830657 and 191312485326913536 exceed the javascript max safe integer of (2^53-1).
Javascript does not handle numbers larger than that in a consistent manner.
Note that in your documents, those numbers are reported as $numberLong, indicating that they are not using javascript's default floating point numeric representation.
To query these number consistently, use the NumberLong constructor when querying, like
{_id:NumberLong("209383449381830657")}
It depends on the version of MongoDB Compass you have (I assume it's +- latest)
As I see, you are using NumberLong for _id field.
You might use NumberLong("...") to handle such fields in MongoDB.
So, better to try search like this
{_id: NumberLong("209383449381830657")}
Can't say for sure how MongoDB Compass handles number you are trying to pass here.
As it should automatically cast values to int32 or int64, but it might be a bit tricky. So, better to define it by yourself to avoid unexpected results.
Some time ago I read an article that it tries to cast to int32, but if it's more than int32 might handle -> then it uses this function
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger
and tries to cast it to int64. My speculation is that problem lives here, but can't say for sure.
In my case the _id contain hex digits.
Filter {_id: ObjectId("62470af3036b9f058552032e")} works
I'm having a problem handling integers with Mongodb that are too large for the standard Int64 format. To give an example of the sorts of numbers we're talking about here: I mean something like 10683171315666225459389678813960790592
Now, I've considered turning this into a Decimal128 and that seems to work. The problem I run into is that I think MongoDB is truncating these values when I convert them. I'm using:
db.NuAIS.find().forEach( function (x) { x.HilbertVal = parseFloat(x.HilbertVal); db.NuAIS.save(x); });
So I read the db, convert each of those string values to Decimal and get: 1.0683171315666225e+37. My assumption was that MongoDB was storing the actual value despite what it declared.
Here's the thing though: these values seem truncated since, when I try to search using the original string on MongoCompass, I get multiple values returned for a supposedly unique string. I assume that mongoDB has truncated the decimals after X strings and so is just returning ones that match the first X digits of the search string, which means you get multiple matches instead of one.
Is my assumption here right? Is there a way to avoid this with decimals or just to skip the whole problem altogether by having ints larger than 64 bits? I'd leave it as a string but I need to work with them as digits, find things that fall within a range and such.
Thank you
I have created the following collection and text index:
db.test1.insert({"name":"kumar goyal","email":'rakesh.goyal#gmail.com',"phoneNo":9742140651});
db.test1.ensureIndex({ "$**": "text" },{ name: "TextIndex" })
Partial search is working for name and email field e.g.
db.test1.runCommand("text",{search:'rakesh'});
returns the record properly but its not working on the phoneNo field.
db.test1.runCommand("text",{search:'9742'});
is not working.
I guess text index is not working on number fields. Is there anyway to make it work in mongodb?
You are inserting the telephone number as a number, but then searching for it as a string.
Perhaps you should consider inserting the telephone number as a string. You're not planning to perform any arithmetic actions on that field are you?
This way mongo will be able to perform textual searches (like the one you gave as an example) on the "numbers" but will treat them as strings.
Mongo DB full text does not support partial search. Hence it was not working, nothing to do with numbers.
Is there a way to handle numbers, which are stored as strings, like integers in mongodb?
e.g.
{
"someKey" : "45646764646"
}
I would like to perform $gte or $lte operations on that value, but it's not possible as long the value for "someKey" is a string. I also would like to avoid of using a dbcursor and make comparisons with java e.g.
If your field someKey contains numbers, consider saving it as NumberLong() . Your driver should allow you to represent that field in your application as a string on most all 10gen drivers.
I would recommend, if possible, converting the strings to ints when you store them in the database. This could prevent confusion in the future, and would save a lot of space due to the storage differences.