So I'm new to MongoDB and is doing some learning on FreeCodeCamp. There is a task where I need to insert a document to database, I successfully completed the task, but the document doesn't seem to reach the database (I've checked it in MongoDB Compass). Here is the code I've wrote:
let mongoose = require('mongoose');
mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
let personSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
age: Number,
favoriteFoods: [String]
}) // making schema for person
let Person = mongoose.model('Person', personSchema) // defining schema model for Person
const createAndSavePerson = (done) => {
var rickSanchez = new Person({
name: 'Rick',
age: 22,
favoriteFoods: ['Ice Cream', 'Nasi Kebuli']
}) // making new document from a model
rickSanchez.save(function(err, data) { // saving the document
if (err) return console.error(err)
done(null, data); // passing the document data to callback
})
};
I tried to call the function, but I got confused because there's a callback function as parameter, I tried to pass done() while calling it but it gets an error. What should I do so my document (rickSanchez) inside the function is being sent to MongoDB?
Any helpful answer would be very appreciated!
Related
Now can you guys please help me with how can I pass the dynamic value while creating the Schema? I want to modify the {CollectionName} in Schema.But I don't want to update the .env file again and again.
I want to pass it as a param
const CardSchema = new mongoose.Schema({
collectionName: {
type: String,
required: true,
}
});
console.log(tabelName);
module.exports = mongoose.model(`${CollectionName}`, CardSchema);
app.post("/form", async (req, resp) => {
const userCard = new CardSchema({
collectionName: req.body.collectionName,
cardName: req.body.cardName,
cardIndex: req.body.cardIndex,
content: req.body.content,
label: req.body.label,
});
await userCard.save();
console.log("user added");
resp.send(userCard);
});
'I did this but I don't think it is the best way
const CollectionName = process.env.COLLECTION_NAME;
'
I have a function that create guild entry for DiscordJS, but when the script start and also if the function is called multiple times, it create around 400 duplicate documents, it create by ID and the ID is unique, so it's not normal
My schema structure only have a ID type String and unique is true
client.createGuild = async guild => {
const exist = await Guild.findOne({ id: guild.id });
if(!exist) {
await Guild.create({ id: guild.id }); // new Guild().save() keep duplicate too
}
}
It look like the if statement doesn't exist
const Schema = mongoose.Schema;
const FooSchema = new Schema({
id: { type: String, index: true, unique: true }
});
const Foo = mongoose.model('Foo', FooSchema);
Foo.createIndexes();
If collection already exists. Create index manually to the collection via atlas or cmd.
You can combine getData and createData functions to one. Here is the example:
const mongoose = require('mongoose');
async function getData(Guild, guild) {
if (!mongoose.connection.readyState) await mongoose.connect('MONGO_URL'); // In case you haven't connect to database
const data = await Guild.findOne({ id: guild.id }); // get data from database
if (!data) {
return new Guild({
id: guild.id,
}); // If no data exists for the guild, return new model
}
return data; // If the data already exists, return that
}
Now if you want to get data from mongodb you just call the function. It automatically create and save a new one if there is not.
Comment if you still have any problem or you have got what you need.
Make sure to call the function with await or it won't return the data.
I have a mongoose Schema like this:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CitizenSchema = new Schema({
SSN: {
type: Number,
required: true,
unique: true,
},
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
}
});
const Citizen = mongoose.model('Citizen', CitizenSchema);
module.exports = Citizen;
and I have a route in my express app that is like this:
router.get('/', (req, res) => {
if (Object.keys(req.query).length === 0) {
// Get all the citizens if there is no query
Citizen.find({})
.select('-SSN')
.then((citizens) => res.send(citizens));
} else {
const query = req.query;
// Add case insensitive to all queries
for (const q in query) {
query[q] = {
$regex: new RegExp(query[q], 'i')
};
}
Citizen.find(query)
.select('-SSN')
.then((citizens) => res.send(citizens))
.catch((err) => res.status(400).send({ msg: 'Bad query request' }));
}
});
So what I do is that if there is not a query, I return all the citizens and if there is a query, I return the query result.
For example if I send a http request to my route with a GET request like http://localhost:5000/api/citizens/, I get all the citizens. And if I send it with a query like http://localhost:5000/api/citizens/?lastName=Doe&firstName=john, I only get the citizens with the first name as John and last name as Doe.
So my problem is that if I try and do a request like http://localhost:5000/api/citizens/?lastName=Doe&q=test, I get an empty array and not the citizens that have Doe as their last name. The query q makes it so that the Citizen.find() does not work properly and does not return the result that I am waiting for.
I will be appreciate it if someone could help me fix this.
You can try using $or in your queries: https://kb.objectrocket.com/mongo-db/or-in-mongoose-1018
I'm trying to access the array of Message Models that is stored in my Conversation Model. However, when I use the populate method to try to store the Message models as an array, only the first Message is showing up.
socket.on('connected', function (data) {
//load all messages
const filter = { roomId: data.roomid };
(async () => {
console.log('searching for Schema');
let conversation = await Conversation.findOne(filter)
.populate('messages')
.exec(function (err, message) {
if (err) console.log('no schema found');
var array = message.messages;
console.log(array);
// printing only first Message
});
})();
});
Conversation Schema
const ConversationSchema = new mongoose.Schema(
{
roomId: {
type: String,
required: true
},
messages: {
type: mongoose.Schema.Types.ObjectId, ref: 'Message'
}
},
{
timestamps: true
}
);
populate method not store message as an array.Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s).Refer this for more detail
To solve your problem modify declaration of messages field in Conversation Schema
messages: [{
type: mongoose.Schema.Types.ObjectId, ref: 'Message'
}]
I have two models in my mongoDB. One is user model and one is event model. What I want to achieve is, when I will add a new event then, that event array will save to my user model's events column array. Till now, I've successfully saved that id of that event to specific user but the problem is only the **objectID** is coming not the property is showing up likeevent name,descriptions`. This is my code:
user model:
const userSchema = mongoose.Schema({
name: String,
events: [
{
type: Schema.Types.ObjectId,
ref: 'Event'
}
]
});
Event model:
const eventSchema = new Schema({
creator: {
type: Schema.Types.ObjectId,
ref: 'User'
},
ename: {
type: String
},
description: {
type: String
},
});
routes.js
router.post('/', (req, res) => {
const event = new Event();
event.creator = '5d9e1ba694f44227e1f54cc0',
event.ename = req.body.ename;
event.save( (err, result) => {
if (!err)
res.redirect('events');
else {
console.log('error', err);
}
});
User.findOneAndUpdate('5d9e1ba694f44227e1f54cc0', {$push: { events: [event] }}, (err, result) => {
if(err) {
console.log(err);
} else {
console.log('event is saved');
}
});
});
for simplicity, I've kept my user id hardcoded. Now, how can I update the $push method of the mongodb so that the whole properties of the event is to save in the user model not only the objectID
I think you may be getting a little confused with how you have set up your model & how mongoose Query Population works.
In userSchema, you have defined that events is an array of type Schema.Types.ObjectId and each 'Event' references a document in the eventSchema schema. Because of this, you cant expect events to be an array of Event.
However, because you have defined this reference in your schema when you query for a document, you can use the Model.Populate method.
const user = await findById("id").populate("events");
This method will find a User and for each Event will look up the Event collection to find a relating document with that ObjectID. This will return a User with the events array being populated with the corresponding Event