Meteor Collections and when to use a schema - javascript

I am starting to build an app and have a collection that is used to create a pet post.
Note: I'm using the following packages to build my collection schemas, Simple Schema https://atmospherejs.com/aldeed/simple-schema
The page that I'm using to insert the data into this particular collection has a section that based on the choice the user makes they are presented with more options.
For example focusing in on one question there are some checkboxes, by default none are selected but if the user selects any checkbox they are given more options to choose from either via checkboxes or text areas. The point is that they will have additional options to choose from based on their selection.
I think the best way to handle how the data is inserted is via the template helpers for that specific section so that's not the question.
Instead where i'm confused is at the collection level and how to Schema that information or if I even need to.
For example let's say you have a question that involves pets.
The question could be: Do you have pets?
The checkbox options could be:
Dogs
Cats
Other
By default all of these checkboxes are unchecked but if the user checks any of the boxes then a text area is revealed (again i realize all of this happens at the Template.events and Template.helpers level).
What my real question is, now that I've set the scenario, is how do you store information like that or schema it to allow these kinds of values.
Assuming that all of the functions to grab this data are all on the Template.helpers level so this is simple a question about how to store kind of data in this scenario.
My notion was to do something like this (using the simpleSchema package):
Pet = new SimpleSchema({
petInstructions: {
type: String,
optional: true,
allowedValues: ['Dogs', 'Cats', 'Other']
}
});
However I'm not certain this is right again let me re-iterate that I do want the checkboxes to have the values 'Dogs', 'Cats', 'Other' and the text area when any of these are checked so that the end-user can enter more information about their pets.
What i'm unclear about is if I'm thinking about how this data's Schema could be or how this kind of information should be stored in the MongoDB.
I feel like there should also be a property for the TextArea input, would that be a good way to think about it?
For example (adding on to the example above):
Pet = new SimpleSchema({
petInstructions: {
type: String,
optional: true,
allowedValues: ['Dogs', 'Cats', 'Other'],
textArea: ""
}
});
Should I just leave another property/value for that particular content?
This is somewhat of a granular level question that understanding something simple like this would help clarify other questions I had.
Thank you.

This is how I would structure it. This is from the autoform instructions for how to validate a field against another field and how to conditionally require a value - https://github.com/aldeed/meteor-simple-schema#best-practice-code-examples
Pet = new SimpleSchema({
pet: {
type: Object,
optional: true
},
"pet.type": {
type: String,
optional: true,
allowedValues: ['Dogs', 'Cats', 'Other']
},
"pet.instructions": {
type: String,
optional: true,
custom: function(){
var petType = this.field('pet.type').value;
// if the user selects a pet type then instructions should be required
if (petType){
return "required";
};
}
}
});
In your old code:
Pet = new SimpleSchema({
petInstructions: {
type: String,
optional: true,
allowedValues: ['Dogs', 'Cats', 'Other'],
textArea: ""
}
});
You are literally stating that for the petInstructions key, you only allow the values to be Dogs, Cats, or Other, but you also want one of the keys to be textArea with some other data, which doesn't make too much sense. SimpleSchema wants you to define a specific data point for each key.

Related

How to declare an array of different types in a Mongoose schema?

I am trying to create a Mongoose schema which contains a field that should be an array that contains different types/objects.
For example:
myArrayField: [
{ type: 'type1', type1Property: 'blabla', type1Property2: 'blabla'},
{ type: 'type2', type2Property2: 'blablo' }
]
I have taken a look at discriminators without any success and I have found mongoose.Schema.Types.Mixed. However, Mixed seems to be very open in terms that Mongo will not check anything about it. I would like to know if I can specify the different types the array can have, something like:
myArrayField: [ SchemaType1, SchemaType2]
So items can follow SchemaType1 OR SchemaType2.
Thank you in advance and regards
Only one type can be assigned to a field. May be you should create one schema with two fields that has different types and required attributes are set to false which is default.

Find Documents whose Subdocument Fields partially match given Criteria with Mongoose

I have using nodeJS and mongoose/mongoDB to build an API. Consider the following model for a generic Model (Gmodel):
{
name: "teleni",
type: "person",
data: mixed
}
The data field in this document is a mixed type so it can be anything, but I intend for it to be a subdocument/object in most cases (depending on the value of the type field). If I wanted to find all the documents that were of type person I would execute the following code:
Gmodel.find({type: "person"}, callbackFunction)
Now consider another instance of the Model:
{
name: "teleni",
type: "person",
data: {
data_type: "event",
date: "Jan 30 2019"
}
}
My issue is that I want to use mongoose to find all documents where the data field is an object/document where the data_type field is "event". I have tried the following code:
Gmodel.find({data: {data_type: "event"}}, callbackFunction)
However nothing is returned when I execute this code because find is looking for Documents where the data field is exactly {data_type: "event"}. So how do I use find to retrieve Documents whose subdocuments (of mixed type) partially match a criteria, similar to how find works on top level fields.
You can use the dot syntax data.data_type to specify a field in subdocument. This way it would match on the basis on this field only, not the entire subdocument as in your original code.
Gmodel.find({data.data_type: "event"}, callbackFunction)

Most simple schema for managing elements and groups

I want to create a list for which I so far have this Schema:
new SimpleSchema({
element: { type: String, optional: true },
note: { type: String, optional: true },
order: { type: Number, optional: true }
});
But now I want to add groups, which also acts like an item:
Pancakes
Vegetables
Tomatoes
Salad
Orange juice
So 'Vegetables' is a group, which have two elements in it, but 'Vegetables' itself is sortable in the main, that means this example-category mainly consists of three elements: Pancakes, Vegetables and Orange juice. Vegetable can be slided down to display the content.
What is the easiest schema for this puprose I mean less nested SimpleSchema-elements - if it is possible without any nested schema?
What I want to do is, that an editor can select some elements on a list and put them to a group. All main elements and the group itself can be ordered by Drag'n drop. So I need the information of the element/group-order.
I hope I can explain what I need to do.
You are creating a tree. There are various ways to represent that in a database and in mongodb in particular: http://docs.mongodb.org/master/tutorial/model-tree-structures/
I often find the array of ancestors to be the best option.

Get part of a list effectively with Mongoose

I have a schema like this.
peopleSchema = Schema({
followerRefs: {
type: [
{ type: Schema.Types.ObjectId, ref: 'peoples'}
],
select: false
},
followRefs: {
type: [
{ type: Schema.Types.ObjectId, ref: 'peoples'}
],
select: false
}
});
Every time, I just want to select part of the followerRefs or followRefs. For example, I want to implement a paging, so I just want to select first 20 in the followRefs, or first 21 ~ 40 in the followRefs.
So, are there any way to get part of the followerRefs with select all of the list?
It seems that I didn't explain my question clearly. I assume that there are over one million entity in the followerRefs in database, and I just want to get the first 20 of them, which mean I just want to get the index of 0~19 of them. So I don't want to load all of the one million entity into the memory.
So I'm wondering whether there are any way to get the first 20 entity without load all of them?
If it's just a list of names, I don't think you should handle the sorting via mongoose nor the backend.
But it depends on the size of data still.
Via javascript(frontend) I would sort the list first depending on what category, then I'd sort it.
Sorting with plain javascript could be complicated and I'm not an expert with it, since I use plugins. XD
So here's a link with a link with an answer about javascript sorting.
Sorting an array of JavaScript objects
Since you are asking about parts of the array, just use javascript slice() function.
var myList = ["Follower1", "Follower2", "Follower3", ...]; //pretend it goes til 20
var page1 = myList.slice(0, 19);

Mongoose - recursive query (merge from multiple results)

I have the following generic schema to represent different types of information.
var Record = new Schema (
{
type: {type: String}, // any string (foo, bar, foobar)
value: {type: String}, // any string value
o_id: {type:String}
}
);
Some of the records based on this schema have:
type="car"
value="ferrari" or
value="ford"
Some records have type "topspeed" with value "210" but they always share o_id (e.g. related "ferrari has this topspeed"). So if "ferrari has top speed 300", then both records have same o_id.
How can I make query to find "ferrari with topspeed 300" when I don't know o_id?
The only solution I found out is to select cars "ferrari" first and then with knowledge of all o_id for all "ferrari" use it to find topspeed.
In pseudocode:
Record.find({type:"car", value:"ferrari"}, function(err, docs)
{
var condition = [];// create array of all found o_id;
Record.find({type:"topspeed", value:"300"}...
}
I know that some merging or joining might not be possible, but what about some chaining these conditions to avoid recursion?
EDIT:
Better example:
Lets imagine I have a HTML document that contains DIV elements with certain id (o_id).
Now each div element can contain different type of microdata items (Car, Animal...).
Each microdata item has different properties ("topspeed", "numberOfLegs"...) based on the type (Car has a topspeed, animal numberOfLegs)
Each property has some value (310 kph, 4 legs)
Now I'm saving these microdata items to the database but in a general way, agnostic of the type and values they contain since the user can define custom schemas from Car, to Animal, to pretty much anything). For that I defined the Record schema: type consists of "itemtype_propertyname" and value is value of the property.
I would eventually like to query "Give me o_id(s) of all DIV elements that contain item Ferrari and item Dog" at the same time.
The reason for this general approach is to allow anyone the ability to define custom schema and corresponding parser that stores the values.
But I will have only one search engine to find all different schemas and value combinations that will treat all possible schemas as a single definition.
I think it'd be far better to combine all records that share an o_id into a single record. E.g.:
{
_id: ObjectId(...),
car: "ferarri",
topspeed: 300
}
Then you won't have this problem, and your schema will be more efficient both in speed and storage size. This is how MongoDB is intended to be used -- heterogenous data can be stored in a single collection, because MongoDB is schemaless. If you continue with your current design, then no, there's no way to avoid multiple round-trips to the database.

Categories

Resources