Moongose - how to customize a field in a scheme ? string and array in the same field - mongodb

I would like to know how I can customize a field where you can use an array and string
eg:
var PostingSchema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
required: true,
trim: true
},
images: Array,
categorie: Array,
ubication:[{ type: Number, ref: 'Place'}],
agg:[{
agg :{ type: String, ref: 'Agg' },
value : String,
make :[{ type: Number, ref: 'Make'}]
}]
});
In the field agg value, I have a problem that can sometimes be of type string and sometimes can be of type array , should be of the array type I populate it with another scheme. How can I do that?
I made a field called "value ->string" and a "make->array" to do if there is a better way?

Related

Define an array of objects, each object is a predefined schema

I have two schemas: Category, and User
Category schema is defined as follows:
title: {
type: String,
required: [true, 'Title field is required'],
unique: true
},
type: {
type: String,
required: [true, 'Type field is required'],
}
User schema
email: {
type: String,
required: true
},
isActive: {
type: Boolean,
default: true,
select: false,
},
categories: [{ /* Category schema object */}],
What I'm trying to implement is when ever a user registers, the categories array must be required, and each object within it must match and follow the predefined category schema and have an objectID.
How to do that with Mongoose?
Import the Category schema into the file where you have defined the User schema, then simply specify the type as array, like this:
const Category = require(....);
.
.
.
.
categories: [{
type: Category,
ref: "Category"
]

How to give iDs to dynamic fields in React-Redux?

I created a simple dynamic fields in React-Redux with a plus button to add as many field as I want (hobbies) of an already existing form. I'm using mongodb as a database and so I have this error that tells me that my fields/data don't have iDs.
so how can I generate iDs for my data?
this below is my model with featherJs. as you can see this is how I added my hobbies array in the existing model called myService. I can see that my hobbies are created in mongo (using Robo 3T) which is great but i'm having difficulty reusing them (hobbies) in an other component in Redux. I'm not sure if I should give IDs to this fields or create a new service just for them. I never coded something in backend so I'm confused. what's the rule for this kind of situations.
Any other suggestions would be helpful.
warning in Redux: Each child in a list should have a unique "key" prop.
error in api : Cast to ObjectId failed for value at path "_id" for model "
const { Schema } = mongooseClient;
const myService = new Schema({
type: { type: String, enum: VALID_TYPES, required: true },
user: {
type: mongooseClient.Schema.Types.ObjectId,
ref: 'user',
required: true
},
comment: String,
hobbies: [{
type: mongooseClient.Schema.Types.ObjectId,
ref: 'hobbies',
default: [],
required: false }],
date: {
begin: { type: Date, default: Date.now },
current: { type: Date, default: Date.now },
end: { type: Date, required: true },
},
}, {
timestamps: true
});
return mongooseClient.model('myService', myService);
};

Populate without _id

I have 2 mongoose schemas, one for stock (info about stock) and one for trade. Where trade represents the trades of a stock (so time, volume, etc). Each stock has a symbol code and the data feed that I get the trades from includes the symbol codes as strings. How would I populate these two collections since I can't use the regular mongoose 'ref' here.
Here are my two schemas:
const stockSchema = new Schema({
symbolCode: { type: String, trim: true },
symbol: { type: String, trim: true },
type: { type: String, index: true, trim: true },
country: { type: String, lowercase: true }
})
const tradeSchema = new Schema({
symbolCode: { type: String, index: true },
symbol: { type: String, index: true },
price: Number,
volume: Number,
time: Date,
currency: { type: String, default: 'USD', uppercase: true, index: true }
})
I want to remove the first two fields in the trade schema so that I can just have some kind of reference to the stock here. How can I do this?
use the populate like this:
MyModel.populate([{ path: 'author', select: 'username name -_id' }]);
the -fieldName or in your case -_id will deduct it from the projection.
For future reference, I solved this using populate virtuals as follows:
stockSchema.virtual('trades', {
ref: 'Trade',
localField: 'symbolCode',
foreignField: 'symbolCode',
justOne: true
})

Is there a way to selectively apply timestamps in mongoose schema?

I'm currently designing a mongoose Schema. The schema is for blog comments, it looks like this:
new mongoose.Schema({
commentedOn: {
type: mongoose.Schema.Types.ObjectId,
required: true
},
author: {
type: String,
required: true
},
contents:{
type: String
},
points: {
type: Number,
default:0
},
timestamps: true
})
The points field is to record the votes of one comment. I don't want to change the timestamp every time when users vote the comment. Is there a way to achieve this? Or should I move the points field out of this schema?
I believe timestamps should be passed in the second argument of the schema.
Regarding your question, the only way I can think of doing this is to not use timestamps and explicitly declare your timestamp fields e.g. createdAt and updatedAt in your schema. Whenever you save or update, you would explicitly set the updatedAt field (or not) depending on the situation.
new mongoose.Schema({
commentedOn: { type: mongoose.Schema.Types.ObjectId, required: true },
author: { type: String, required: true },
contents: String,
points: { Number, default: 0 },
createdAt: { type: Date, default: Date.now },
updatedAt: Date
});

database design for a market

I want to design database for a market with simple and few objects for selling using NodeJS, MongoDB and Mongoose. Because I'm new to MongoDB and NoSQL designs, I need a guide for designing it.
My implementation is here:
var orderSchema = new Schema({
orderId: Schema.Types.ObjectId,
orderType: {
type: String, enum: ['OBJEC1',
'OBJECT2',
//other objects
], default: 'ALBUM'
},
price: { type: String, enum: ['PRICE1', 'PRICE2', 'PRICE3'] },
coverPhoto: { type: String, default: '' },
photos: [{
address: { type: String, default: 'media/uploads' },
}],
orderQuantity: { type: Number, default: 1 },
isChecked: { type: Boolean, default: true },
date: { type: Date, default: Date.now }
});
Besides, I'll save reference of each order to its related user. Am I right, or not? Thanks a lot.
The way you designed your schema based on the logic seems good. One thing is you have used default in all the fields.
First, you should understand that default is optional and default is used only when you want to populate some value during the data is created.
Example: you have default for date field, here it is good to have. You don't want to manually assign a date during processing the data. So only unless your field should have common default value when creation then you go ahead otherwise remove the default field and make sure the data is inserted properly.
you can use required attribute in case some field is mandatory to create a document in the collection. I guess orderType a mandatory field so don't miss it ever during insertion so make it as required: true.
var orderSchema = new Schema({
orderId: {
type: Schema.Types.ObjectId
},
orderType: {
type: String,
enum: ['OBJEC1','OBJECT2']
},
price: {
type: String,
enum: ['PRICE1', 'PRICE2', 'PRICE3']
},
coverPhoto: {
type: String
},
photos: [{
address: {
type: String
}
}],
orderQuantity: {
type: Number
},
isChecked: {
type: Boolean,
default: true
},
date: {
type: Date,
default: Date.now
}
});