I have a server which stores records representing Objects, and which uses Mongoose to manage these records. I want to be able to query/update/etc. all objects with a simple API (i.e. a single endpoint). Different types of Objects have some identical attributes, and some different attributes, so a single, static Object schema won't do. Instead, I still want to have a single schema, but I want to be able to change it slightly by adding/deleting fields when I create each new Object, with the fields which are/aren't present depending on the type of the Object. I don't want a mixed schema, because I want error validation for each type of Object. I want a single schema (as opposed to a different schema for each type of Object) so that I can just do
Object = mongoose.model('Object', ObjectSchema);
Object.findOne({objectType: "type1"}, function(err, model) {
...
});
So basically, I want field validation, while still maintaining some flexibility for attributes, and a single point to query/update/etc. my Object records. If I change the schema with each new Object, recompile it into a model, and create a new instance of that model, will all the instances of the different models (compiled from different modified versions of the same schema) still be queryable as above?
Obviously, I'm new to Mongoose. I just talked a lot about the schema here, and I honestly don't know whether I should have used the word "model" in place of "schema" in some places. I just don't know how I can accomplish all of this. Let me know if I make no sense.
We are successfully using the mongoose model inheritance and discriminator functionality for a very similar scenario. See here for an example:
http://www.laplacesdemon.com/2014/02/19/model-inheritance-node-js-mongoose/
You might also be able to use this plugin:
https://www.npmjs.com/package/mongoose-schema-extend
Related
This question already has answers here:
Why does Mongoose have both schemas and models?
(6 answers)
Closed 8 years ago.
i'm suprised this question hasn't been asked before, makes me kinda worry actually about my ability to understand how things work on my own....
In object oriented programming, we firstly define the abstraction, the class, and then we instantiate many concrete objects, based on the abstraction.
Why do we need to define both a Schema and a Model with Mongoose ? Aren't these 2 steps the same thing ?
The simple reason is that "model" and "schema" are two totally different things.
A "schema" defines the type constraints and other logic than can refer to how you want to "define" an object. Thee are many methods to do this including basic type rules right through to defining certain methods for validation or even dynamic field construction. A Schema is basically a extended definition of an object.
A "model" is something that actually "ties" to storage. In that it means there is something defined in "where" to actually store the the information. The "methods" used to interact with storage are also generally associated with a model. So you can save, or find or delete based on the model association. A "schema" can therefore be "tied" to various "models", as a model is all about a storage location.
So in the basic mongoose sense, a "schema" is not something that is necessarily tied in a "one to one" relationship to a "model". A schema can have many models and therefore the separation is made.
When looking at tutorials there is often a delineation between a schema and a model, particularly when dealing with mongoose/mongodb.
This makes porting over to postgresql somewhat confusing, as 'models' don't seem to exist under that system. What is the difference the two approaches?
For example, what would be a postgres/sql ORM equivalent of this line?
(mongoose and express.js):
var userSchema = schema.define('local', {
username: String,
password: String,
});
module.exports = mongoose.model('User', userSchema);
In mongoose, a schema represents the structure of a particular document, either completely or just a portion of the document. It's a way to express expected properties and values as well as constraints and indexes. A model defines a programming interface for interacting with the database (read, insert, update, etc). So a schema answers "what will the data in this collection look like?" and a model provides functionality like "Are there any records matching this query?" or "Add a new document to the collection".
In straight RDBMS, the schema is implemented by DDL statements (create table, alter table, etc), whereas there's no direct concept of a model, just SQL statements that can do highly flexible queries (select statements) as well as basic insert, update, delete operations.
Another way to think of it is the nature of SQL allows you to define a "model" for each query by selecting only particular fields as well as joining records from related tables together.
In other ORM systems like Ruby on Rails, the schema is defined via ActiveRecord mechanisms and the model is the extra methods your Model subclass adds that define additional business logic.
A schema is fundamentally describing the data construct of a
document (in MongoDB collection). This schema defines the name of each item of data, and the type of data, whether it is a string, number, date, Boolean, and so on.
A model is a compiled version of the schema. One instance of the model will map to one document in the database.
It is the model that handles the reading, creating, updating, and deleting of documents.
A document in a Mongoose collection is a single instance of a model. So it makes sense that if we're going to work with our data then it will be through the model.
A single instance of a model (like a User instance in var User = mongoose.model('User', userSchema);) maps directly to a single document in the database.
With this 1:1 relationship, it is the model that handles all document interaction - creating, reading, saving, and deleting. This makes the model a very powerful tool.
Taken from "Mongoose for Application Development", by Simon Holmes, 2013
I imagine models as classes created from a schema (maybe I am mistaken).
MongoDB stores everything in BSON , which is a binary format. A simple Hello World BSON document might look like this internally:
\x16\x00\x00\x00\x02hello\x00\x06\x00\x00\x00world\x00\x00. A computer can deal with all that mumbo-jumbo, but that's hard to read for humans. We want something we can easily understand, which is why developers have created the concept of a database model. A model is a representation of a database record as a nice object in your programming language of choice. In this case, our models will be JavaScript objects. Models can serve as simple objects that store database values, but they often have things like data validation, extra methods, and more. As you’ll see, Mongoose has a lot
of those features.
Taken from "Express in Action", by Evan Hahn, 2016
In Short:
A Mongoose model is a wrapper on the Mongoose schema. A Mongoose schema defines the structure of the document, default values, validators, etc., whereas a Mongoose model provides an interface to the database for creating, querying, updating, deleting records, etc.
Reference: Introduction to Mongoose for MongoDB - FCC
I am following this example: Using NHibernate with ServiceStack
In the Contacts class library is there way to not have to create another Product class since we already have the Model or is this required? Seems like dependency injection could be used here.
Also could I move the model and mappings into thier own class library outside of the Services project?
How would I return model that had a property that was another model? I.e. Say we had an employee model that was linked to a person model by Id and the person model contained the employee Date Of Birth, I am not seeing how I would return that.
You don't have to create seperate models (or DTOs), however, I think when dealing with different ORMs the custom DTOs will make life easier. You can easily translate the properties with ServiceStack's property translater or something like AutoMapper.
I would create your DTOs in the manner that you want others to consume them. In other words you DTO's don't need to align with the underlying tables. You can combine models and flatten the data into useful DTOs. In your example the Employee class could expose the date of birth and any other person properties.
You can easily keep your DTOs in a separate project. I have done this in projects where I wanted to re-use the DTO classes elsewhere without including the services.
Scenario:
I am fetching different entity objects from my Core Data database and collecting them all into a single NSMutableArray. I have no problem massaging the data in the array and saving back to the Database. I need to save the state of the array between application launches.
Question:
What is the best way to save a description of the entity objects in the array as well as the order they are in the array? (I have already tried saving the array to a dictionary, encoding the entity objects in to NSData. Didn't work because I couldn't decode the entity object.)
What is the best way to restore the array and fetch the entity objects from the database?
Thanks guys.
You have a couple different options. If the order of the objects in the "array" does not change too much, you can add an entity "MyFavoriteEntities" or some such, and give it a to-many ordered relationship to the entities you want to be included.
Then, all you do is load that single MyFavoriteEntities object, and access all the other objects through that relationship.
NOTE: Currently, ordered relationships are not supported on iCloud.
The alternative (and in lots of situations, the preferred method) is to add an "ordering" attribute to your entities. Keep that updated with the order of your objects. Then, you can easily fetch the objects by giving a SortDescriptor for the "ordering" field. now, your objects will be fetched in the order you want.
I'm developing a rather large XML Schema to integrate multiple disparate systems. Each system has messages that consist of multiple fields. I've written the schemas so that each field is represented as a type (either simple or complex), while the entire message is represented as an element with a sequence of multiple types.
When defining types using XSD, what is the convention in terms of how you break up your files?
I've been going down the path of having a separate XSD file for each type that I am defining, then a single XSD file that defines the message and imports the required XSD files.
Here's a simplified example showing the structure (can't post images, no reputation).
Type schemas (fields) have a namespace ending in "types", while message schemas have a namespace ending in "messages".
My reasoning was that it would be easier to compose new types using existing types if they were defined in their own file, and that versioning types might be easier.
Is there a better approach? I'm relatively new to XML and Schemas. Thanks in advance.
It makes no sense to have one schema per type. One schema per domain area, yes, but not one per type.
For instance, you might have one schema to define types related to customers, and another schema to define types related to products. You might have a separate schema to define common types like people and addresses, which might be used by the customer schema and also by the product schema (product sales rep, vendor address).
You might combine these in a schema related to order processing, since it involves orders made by customers for products.
Are the separate xsd files you created completely unrelated to eachother? For example if one xsd file handles the sales domain and the other one handles the payments domain, you should give each schema a unique domain specific targetNamespace. This approach is called "Heterogeneous namespace design" and you are using it now. I believe it is best suited for your requirement. Since you are having multiple disparate systems it is better to maintain them in separate xsd files with different targetNamespaces. This enhances re-usability and reduces redundancy of types/fields. It also prevents namespace collisions. However if you have a large number of imports it becomes a challenge to manage and there will be dependency on the granularity of the types defined in the imported schemas.
If they are related to each other you should go for "Homogeneous namespace design".
There are two other approaches for XML Schema design:Homogenous Namespace Design and Chameleon Namespace Design which may not best suit your specific requirement. You can further get details on the benefits/drawbacks of all these three different schema design approaches at http://technologyandleadership.com/three-schema-design-approaches/