Meteor mongo save/insert numbers are converted to string - string

I just noticed that whenever saving anything in MongoDB using a predefined variable the data types are changed from Number and Boolean to String
Orders = new Mongo.Collection("Orders");
Orders.update({_id:"12345"},{$set:{price:5.5}) //this works
var price = {price: 5.5};
Orders.update({_id:"12345"},{$set:price}); //this is not working anymore in the mongo collection price is saved as String "5.5" not as a number, same goes for Boolean values
Can anyone help me in what is going on recently? Changing the whole application to use the first approach is not a solution as I have thousands of updates generated by my code which worked perfectly before.

Can you try this when declaring the variable:
var price = {price: Number(5.5)};
Orders.update({_id:"12345"},{$set:price});
By this way, I think it makes sure that 5.5 indeed is a number when it tries to update the related data. For the booleans you can use Boolean(true) as well I guess

Related

Mongo db find operation query ($gte, $lt) is not working

I had a problem using query with MongoDB.
The problem was solved but I wanted to check if there was any other approach I could have taken.
At first, my model (Ad) had a property of price: {type: String}, and I tried to find by queries $gte and $lt to get ads with a price within a given range.
After reading online I figured that query operations are not working on String type properties.
Then even after changing the type to Number - price: {type: Number} - the find function didn't work properly on the price, even though on other properties which were type Number it worked as it should.
In the end, I just deleted the whole database and reupload it, and then everything worked properly (haven't changed a thing).
Has anyone had this kind of problem and solved it differently?
I'll first start by assuming you're using mongoose as the "types" you've pasted look like mongoose schema types.
You need to separate these two concepts:
The schema that represents data at the app level
The actual data in the DB.
Let's say I have this schema for a certain collection:
{ name: String }
But in the actual database there is only one document in that collection that looks like this:
{ price: 5, product_id: 1 }
Then when I query the data what do you expect to happen? do you expect mongoose to automatically generate a name for that document and delete the actual fields?
The reason it didn't "work" as you intended was that all the values were saved as string, changing the Schema does not retroactively update the database, so when you use $lt and $gte it uses string comparison which means "10" is less than "9" because that's how string comparison work.
The schema does help with newly inserted data and can cast it to the right type if supported, for that you should check the docs with what values are available.

RethinkDB using .Update and Variables

I want to manipulate a field for a given ID, and the field depends on user Input. So I have...
var fieldName = (got from the user)
r.db('DataBase').table('table').get(ID).update({fieldName: 'YES'})
This doesn't work because RethinkDB doesn't recognize 'fieldName' as a variable, and instead makes a new field called fieldName, instead of the value stored 'fieldName'.
Is there a way around this or no?
Thank you!
Found the way to do it!
Add [] around your variable. This apparently works so far
r.db('DataBase').table('table').get(ID).update({[fieldName]: 'YES'})

How to make #DbLookup in XPages verify the existence of a value in another database?

I have an XPage that is doing an #DbLookup with a user's input and trying to find that value in a view in a different database yet on the same server.
I have already verified that the view is in fact sorted by the first column and therefore #DbLookup friendly. The following code below appears in the server-side Javascript OnClick event handler for a button on my XPage.
My problem is that the an error occurs when trying to assign the value of lRep to the 'firstNameLabel'. lRep is returning a null value from the dbLookup even though the a record under the 'FirstName' field exists with the key 'P301993'. This dbLookup should be finding a returning a single 'FirstName' result. However, it is not.
var resultLabel = getComponent("firstNameLabel");
var dbName = new Array(#DbName()[0],"UKCSandbox.nsf");
var lRep = #DbLookup(dbName,"customerLookup","P301993","FirstName");
resultLabel.setValue(lRep.toString());
Unless your formatting was lost in copy and paste, your code has flaws. This is not Java, this is JavaScript. Line endings matter and functions don't act on the object, but return a value. Also #DbLookup returns a string when you have exactly one match, so checking for string doesn't help you.
Your code should look like that:
var ukcNumber = Registration.getItemValueString('UKCNumber').toUpperCase();
var resultLabel = getComponent("ukcNumberLabel");
var dbName = #DbName();
dbName[1] = "UKC\\UKCSandbox.nsf";
var lRep = #DbLookup(dbName,"customerLookup",ukcNumber,1);
resultLabel.setValue((lRep) ? "Success" : "Failed");
Does that work for you?
Update: 2 things to check:
does the lookup work in the same database using #DbName?
XPages have the same security constraints as Java agents. Do you have enough rights in the server document to do a 'get value from other database'? Default is No!
Have you tried making the dblookup work outside of xpages, i.e. with ScanEZ or in the Notes client?
Check your ukcNumber variable so it contains a value.
Edit
Check so the user has rights to do the lookup in the other database.
Also try a similar code on an old Notes Form and see if you get the same result.
Why can't you use keyword '[FAILSILENT]' in your #DBLookup call. It'll return "", if no entry matches with your key.
If you still have issues, use SSJS/java code to see where it's breaking up.

How do I remove the need to convert _id (as a string) to new ObjectID(string) in nodejs / mongodb native library?

Each time I have to perform a query involving _id, I have to do new ObjectID( _idAsString) in order for it to work. I realize mongo tests the object, not the value itself, but this is adding a lot of overhead and I may miss converting it in some places.
The _id goes to the client where the ObjectID( string ) is turned to string and when it comes back from the client, I would have to remake it into ObjectID( string ). I will mention that "string" is the actual value generated by mongo, something like 123a1b12dc...
If there is another good/complete library with such a internal functionality, I would love to try it out.
There are some Node.js object mappers which provide this functionality. Take a look at Mongolia.
https://github.com/masylum/mongolia#mappings-and-type-casting

Node.js + Mongoose / Mongo & a shortened _id field

I'd like the unique _id field in one of my models to be relatively short: 8 letters/numbers, instead of the usual Mongo _id which is much longer. Having a short unique-index like this helps elsewhere in my code, for reasons I'll skip over here. I've successfully created a schema that does the trick (randomString is a function that generates a string of the given length):
new Schema('Activities', {
'_id': { type: String, unique: true, 'default': function(){ return randomString(8); } },
// ... other definitions
}
This works well so far, but I am concerned about duplicate IDs generated from the randomString function. There are 36^8 possible IDs, so right now it is not a problem... but as the set of possible IDs fills up, I am worried about insert commands failing due to a duplicate ID.
Obviously, I could do an extra query to check if the ID was taken before doing an insert... but that makes me cry inside.
I'm sure there's a better way to be doing this, but I'm not seeing it in the documentation.
This shortid lib https://github.com/dylang/shortid is being used by Doodle or Die, seems to be battle tested.
By creating a unique index on _id you'll get an error if you try to insert a document with a duplicate key. So wrap error handling around any inserts you do that looks for the error and then generates another ID and retries the insert in that case. You could add a method to your schema that implements this enhanced save to keep things clean and DRY.

Resources