How to map an input field as different field in mongodb - node.js

Suppose I am inserting data in MongoDB as
db.collection.insertMany([{username:'Jack',msg:'hello'},{username:'Jenny',msg:'hello world'},{username:'Rose',msg:'Hi howz You'}])
now I want this data to be inserted as this:
{account_username:'Jack',msg:'hello'}
{account_username:'Jenny',msg:'hello world'}
{account_username:'Rose',msg:'Hi howz You'}
and NOT THIS:
{username:'Jack',msg:'hello'}
{username:'Jenny',msg:'hello world'}
{username:'Rose',msg:'Hi howz You'}
I am using mongoose in my NodeJS code, can I do something in Schema so whenever input is username it will automatically refer to account_username of my defined mongoose Schema.

If using mongoose with mongoDB one can easily do this using mongoose virtual functions functionality, Mongoose Virtuals
Mongoose Viruals have Setters and Getters, Which have functionality to define columns with different name

Related

Node mongoose model first argument

I'm learning node and mongo and use mongoose for my modeling.
In the mongoose docs it says that mongoose.model, the first argument is singular name of the collection of your model. I find this hard to understand.
My db name is CRMdb is this also the collection name?
My model looks like this const Contact = mongoose.model('Contact', ContactSchema);, How does mongoose know automatically detect for the plural version of my model name?
`
A collection is like a table, not a db, so no.
You can also do it like this const Contact = mongoose.model('Contact', ContactSchema, 'contacts'); (in this case the collection name is contacts). Not really sure how they create the plural, but I don't really think it matters.

Create dynamic collection in MongoDB using Sails.js

I am working with SailsJs+MongoDB API. I have to create New colletion in mongoDB .Name of colletion will be in request Parameter.
example:
Suppose I want to create 'Users' collection in 'mongoDbDatabase' database
by following request.
{
"collectionName" : "Users",
"dbName" :"mongoDbDatabase"
}
Now is there any way to create dynamic collection in mongoDB using req.param('collectionName) variable ?
To use all the tools that Sails provides, you have to add code (before you start your app) for each Model / Collection you are planning to interact with. As a result, creating a collection dynamically will mean you can't take advantage of the whole data - framework sails provides.
Are you sure you need a dynamic collection? Why not a defined collection differentiated by attributes?
If you really need to do this from Sails, it looks like you can get access to the underlying raw mongo database:
var db = AnyModel.getDatastore().manager; // the database will be as defined in config/models.js or config/connections.js
var collectionName = 'Widgets';
db.createCollection(collectionName);
// note, even if this works, something like 'Widgets.find' will not.

Meteor Mongo BulkOp turning ObjectID into plain object

While using Meteor, I sometimes access the underlying Node Mongo driver so I can make bulk updates and inserts.
const bulk = Coll.rawCollection().initializeOrderedBulkOp();
bulk.insert({key_id: Mongo.Collection.ObjectID()}); // note key_id is an ObjectID
...
bulk.execute();
But the value of the key_id fields ends up being the plain subdocument {_str: '...'} when I look in the database after the insert.
Is there any way to use bulk operations in Node's Mongo library (whatever it is Meteor uses) and keep ObjectID's as Mongo's ObjectID type?
(There's many posts about the nature of the different ID types, and explaining Minimongo, etc. I'm interested specifically about the bulk operations converting ObjectID's into plain objects, and solving that issue.)
From Neil's top-level comment
On a native method you would actually need to grab the native implementation. You should be able to access from the loaded driver through MongoInternals [...]
Mongo.Collection.ObjectID is not a plain ObjectId representation, and is actually a complex object for Meteor internal use. Hence why the native methods don't know how to use the value.
So if you have some field which is an ObjectId, and you're using some method of a Meteor Collection's rawCollection (for example,
.distinct
.aggregate
.initializeOrderedBulkOp
.initializeUnorderedBulkOp
), you'll want to convert your ObjectId's using
const convertedID = new MongoInternals.NpmModule.ObjectID(
originalID._str
);
// then use in one of the arguments to your function or something
const query = {_id: convertedID};
before calling the method on them.

Mongoose Schema vs Mongo Validator

Mongo 3.2 have document validation, can we use the same to define a schema instead of using mongoose to do so.? For example :
Mongoose
userschema = mongoose.Schema({
org: String,
username: String,
fullname: String,
password: String,
email: String
});
MongoDB
db.createCollection(
"example",{
validator:{
$and:[
{ "org":{$type:"string"}},
{ "username":{$type:"string"}},
{ "fullname":{$type:"double"}},
{"password":$type:"string"}},
{"email":{$type:"string"}}
]
},
validationLevel:"strict",
validationAction:"error"
})
What ar ethe difference between these tow and can we provide an optional field using validator as in schema ?
I use both because they each have different limitations:
Mongoose validators do not run on all types of update queries, and validators only run on paths with values in the update doc because the validators can't know if, for example, a required field is already defined in the database but not in your client's memory (see issue). This is a major reason to use MongoDB validators [in addition to Mongoose validators].
update validators only run on $set and $unset operations (and $push and $addToSet in >= 4.8.0).
So you can have a field with required: true in your Mongoose schema, but an update operation will not actually require that field! A MongoDB validator can solve this:
db.runCommand({collMod: "collection", validator: {myfield: {$exists: true}}})
MongoDB for the most part cannot reference other fields during validation. For example, you can't say {field1: {$lte: field2}}. Mongoose validators can reference other fields.
You can do some very basic types of cross-field referencing though:
{validator: {myfield1: "Value 1", $and: [/* other validators */]}
This comes in handy if you're using Mongoose discriminators (inheritance) and have different requirements for each child type.
MongoDB does not provide "nice" errors in case of validation failure; it simply says something like writeError: {code: 121, errmsg: "Document failed validation}. Mongoose will typically say something like Path 'foo.bar' failed validation.
MongoDB is fixing this in v4.6.
Abilities that they share:
Type validation. Mongoose by default attempts to cast values to the type specified in the schema. MongoDB with the $type attribute will cause a validation failure in case of a type mismatch.
Min and max number values. Mongoose uses min and max attributes on the schema. MongoDB uses $lt, $lte, $gt and $gte.
String enums. Mongoose uses enum: [values]. MongoDB uses $in: [values].
String length validation. Mongoose: minlength: 2, maxlength: 10. MongoDB, use a regex: {fieldname: {$regex: /.{2,10}/}}.
Array length validation. Mongoose you have to use a custom validator. MongoDB: {fieldName: {$size: 2}}.
String RegExp matching. Mongoose you have to use a custom validator.
The first bullet point is a major one. MongoDB does not have transactionsnow has transactions, but it does have powerful (and cheap) atomic updates. You often times can't reliably or safely read -> change -> validate -> write with MongoDB, so using MongoDB native validators is critical in these cases.
Since the last answer, MongoDB 4.0 have been released.
the $jsonSchema feature now have more options than base mongoose Schema validator. (you can add custom validator in mongoose, though).
the use of allOf, oneOf, anyOf and not operator permit to do complex matching, similar to Mongoose discriminator.
with the $exec command, it is possible to compare the value of two field of the same document like so :
db.createCollection("test", {
validator : {
$expr : {$gte: ["$budget", "$spend"]}
}
})
will validate that the value of the field budget must be greater or equal than the value of spend.
(example adapted from mongodb documentation)
MongoDB still have the problem of non informative error message.
Personnally, I validate my data client side (making request to database if necessary to check for uniqueness). This way, the validation of mongodb have error only if there is concurent modification (someone modified the data between the moment you check and the moment you save). when there is mongodb error, I can simply rerun the client side validation to see what wrong.
I think Mongoose is used to it's fullest when used with a find-modify-save strategy, witch permit to use all the feature. this strategy need the use of versioning or locking to prevent concurrent modification.
when going for atomic update (using mongodb operator, update or findAndModify), with the current state of mongodb validation, I would be tempted to not use mongoose (or only use it for the connection management)

Dynamic Schema in Mongoose

I am developing a web application using MEAN stack.
In my application User performs a calculation operation ,
I am using mongodb map reduce and writing the output to a collection in DB (say calculated_result)so that user can see the result later,
Hence I have created a dynamic MR output collection named Calculated_result_userID.
Now the problem is "How can i defined a dynamic schema for this Collection"
I am using MONGOOSE
Eg.
var variableCollectionName = "calculated_result_"+userId;
mongoose.model(variableCollectionName, mySchema);
Thanks in adavance

Resources