how add elements in collection with Mongoose - node.js

I try to learn databases, specially mongoDb.
I use Mongoose and i try to add elements in my collection. I know that's a basic question but i don't understand where can be my problem
there is my code:
mongoose.connect("mongodb://localhost:27017/hackathon", (error)=>{
if (!error){
console.log("YESSS")
}
else {
console.log("rip")
}
var friend = { firstName: 'Harry', lastName: 'Potter' };
mongoose.connection.db.listCollections().toArray(function (err, names) {
console.log(names); // [{ name: 'dbname.myCollection' }]
module.exports.Collection = names;
});
});
the mongoose.connect function correctly, and the console.log gives me
{ name: 'mycol',
type: 'collection',
I tried to do :
collection.push but he doesn't know it.
i tried something like that
var dbo = db.db("mycol");
dbo.collection("mycol").insertOne(friend, function(err, res) {
if (err) throw err;
console.log("1 document inserted");
db.close();
});
(i found it on stack overflow but that do nothing)
Is there something i miss?
I think it's an easy thing and i just miss something in my comprehension.
Sorry for my english and thanks !

I used an other technique, i don't know if its the best solution so i created a schema (with differents elements, name, number-phone etc), and with a new and save, i found my solution.
Thanks for your answers

Related

Mongoose Updating Certain Fields of a Document

I'm trying to implement an update method for our API and I'm kinda new to the Node so I didn't know what would be the best practice to carry out the task of updating some fields of a document. Let me elaborate, we have a user model which keeps basic info of a user like name, age, sex, school, bio, birthday etc. Our update method should work as this, the request of the method includes the new values of the fields provided such as {bio:'newBio'} or {school:'newSchool', name:'newName'} I must update the provided fields with the provided data and leave the rest as they are. I was wondering what the best approach to the problem at hand would be. Thanks in advance
The easiest approach what i can think of is to use $Set to perform the update operations.
an example would be :
var updatedUsers= function(db, callback) {
db.collection('users').updateMany(
{ "_id": "value"},
{
$set: { bio: "new bio" }
}
,
function(err, results) {
console.log(results);
callback();
});
};
and invoke your above function as :
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
updatedUsers(db, function() {
db.close();
});
});

Mongoose nested reference population

I'm having trouble understanding some of the concepts behind mongoose's populate methods. I had an embedded approach working first, although, as I feared a big overhead of data and out-of-sync documents going around I tried changing the paradigm to ref other documents.
My Schema is similar to the following (removed irrelevant properties):
var userSchema = mongoose.Schema({
name: {type: String, default:''},
favorites:{
users:[{type: Schema.Types.ObjectId, ref: this}],
places:[{type: Schema.Types.ObjectId, ref: PlaceSchema}]
}
});
module.exports = mongoose.model('User', userSchema);
Now I'm trying to get a User's favorites like this:
User.findOne({_id: currentUser}).exec(function(err, user){
console.log(user);
if (err)
throw err;
if(!user){
console.log("can't find user");
}else{ // user found
user.populate('favorites.users');
user.populate('favorites.places');
// do something to the 'user.favorites' object
}
});
Although this doesn't work as intended, as both user.favorites.users and user.favorites.places come up undefined.
I thought that I could populate as above, but apparently, that's not the case. From what I read, I must be missing something indicating (maybe) the model of the ref'ed document? This flow is very new to me and I'm kinda lost.
Is there anyway I can get an array of users and places by populating my query result as above? I tried populate chained with exec and it doesn't work either. Is there a better way to achieve this result?
EDIT: In case it's needed, in the DB, a User document shows up as:
{
"_id": "56c36b330fbc51ba19cc83ff",
"name": "John Doe",
"favorites": {
"places": [],
"users": [
"56b9d9a45f1ada8e0c0dee27"
]
}
}
EDIT: A couple more details... I'm currently storing/removing the reference ObjectIds like this (note targetID is a String):
user.favorites.users.push({ _id: mongoose.Types.ObjectId(targetID)});
user.favorites.users.pull({ _id: mongoose.Types.ObjectId(targetID)});
Also, I need to populate the users and places with their respective documents aswell, I think that might not be clear in my original question.
Well, I figured out what I needed by paying proper attention to the docs (and also with #DJeanCar 's (+1'd) help/pointers).
By Mongoose's docs regarding Populating across multiple levels, I've reached this solution:
User.findOne({_id: currentUser})
.populate({path:"favorites.users", populate: "name"})
.populate({path:"favorites.places", populate: "name"})
.exec(function(err, user){
if(err)
throw err;
if(!user){
console.log("couldnt find source user");
}else{
// here, user.favorites is populated and I can do what I need with the data
}
});
Also, from what I could tell, you can also pass select: "field field field" in populate()'s options, should you need to filter the document fields you require after population.
Hope this helps someone with similar issues!
Try:
User
.findOne({_id: currentUser})
.populate('favorites.users')
.populate('favorites.places')
.exec( function (err, user) {
// user.favorites.users
// user.favorites.places
});

Update data in MongoDB with Mongojs using findAndModify()

Yet another first-timer problem here. This gets data from a database and displays it in some text fields (that part is not shown in the code below) and after the user edits it the data should be updated in the database via the findAndModify() method and I think this is where the issue lies. There are no errors, it just doesn't do anything. EDIT The following error is received: MongoError: Either an update or remove=true must be specified
server.js
MongoClient.connect("mongodb://user:secretPassword#aws-us-east-1-portal.7.dblayer.com:10712,aws-us-east-1-portal.10.dblayer.com:10316/database", function(err, db) {
if (err) throw err;
var contactList = db.collection("contactList");
app.put('/contactList/:id', function(req, res) {
var id = req.params.id;
console.log("edited: " + req.body.name); //works up until here
contactList.findAndModify({
query: {_id: mongojs.ObjectId(id)},
update: {$set: {name: req.body.name, email: req.body.email, number: req.body.number}},
new: true
}, function (err, doc) {
res.json(doc);
})
});
controller.js
$scope.update = function() {
$http.put('/contactList/' + $scope.contact._id, $scope.contact).success(function(response) {
refresh();
})
};
If this were me I would first do a couple of things:
Before your call to findAndModify just do a simple find using your query. Make sure you can actually find the object using your query. If that works you know that the 'find' part of the findAndModify is probably ok.
Do some console logging inside the callback handler of the findAndModify call. As it stands you do not do anything if an err is returned from the findAndModify call. It is possible your call is returning an error that you are just ignoring and it may provide some additional insight into your problem.
I would try these two first and see if it helps.
Update:
Example using native:
collection.findAndModify(
{ field: 'some value' },
[],
{ $set: { field2: 'some new value' } },
{ new:true },
function(err, doc) {
//handle err and doc
});

nodejs + mongoose - how to use forEach in nodejs

I'm still learning about node.js and mongodb. I'm trying to write simple app with nodejs and mongoose. My mongoose schema:
var todoSchema = new Schema({
task: String,
description: String,
date: Date,
status: String,
checklist: Boolean,
pic: String
});
I have collection named todos I'm trying to get the content of todos using this code:
apiRoutes.route('/todos/detail')
.get(function(req, res){
Todo.distinct( "pic" ).each(function(doc){
Todo.find({"pic": doc.pic}, function(err, todo){
if (err)
res.send(err);
var finalResult = [];
finalResult.push(todo);
res.send(finalResult);
});
});
});
But I got this error:
Object #<Query> has no method 'each'
Any idea to solve this? Really appreciate for the help.
From what I gather in your question, you don't necessarily need the loop since with the distinct pics array you are iterating over, you are using it to query the collection for each pic, which is
essentially equivalent to just querying the whole collection as sending the resulting array of documents returned from the query:
apiRoutes.route('/todos/detail').get(function(req, res){
Todo.find({"pic": { "$exists": true }}, function(err, todos){
if (err) res.send(err);
res.send(todos);
});
});
Unless you want to get a distinct list of pics, get the todo items with those pics you could try the following approach:
apiRoutes.route('/todos/detail').get(function(req, res){
Todo.find().distinct('pic', function(error, pics) {
// pics is an array of all pics
Todo.find({"pic": { "$in": pics } }, function(err, todos){
if (err) res.send(err);
res.send(todos);
});
});
});
For starting you should try with .forEach() instead of .each() first :)
Here you can see the forEach doc.

Mongoose Returned Model can't be updated

I'm pretty new to Mongoose/Mongo and node.js, so I suspect this is just a misunderstanding on my side, but...
The code sample below is the smallest failing example, not specifically my use case.
var User = app.db.model('User');
User.find({email: 'm8#test.com'}, function (err, models) {
models[0].update(function(err, mod) {
console.log(err.message)
});
});
This results in the following error: After applying the update to the document {_id: ObjectId('54647402cb955748153ea782') , ...}, the (immutable) field '_id' was found to have been altered to _id: ObjectId('546d9e0e539ed9ec102348f9')
Why is this happening? I would have thought calling update on the model returned from the initial find would have been fine.
Please note: in my use case there are things happening in between the find and the update. Specifically, I'm doing something similar to:
model.property.push(objectId)
Which I then want to commit via the update.
I'm sure this is a straight-forward issue, but I can't see anywhere in the docs I may be getting it wrong.
All help appreciated.
UPDATE:
What I actually needed to do was:
var User = app.db.model('User');
User.find({email: 'm8#test.com'}, function (err, models) {
models[0].save(function(err, mod) {
console.log(err.message)
});
});
Using 'save' rather than 'update'
I don't know if I understood
Find and Update ( for example using express )
var email = req.params.email;
User.find({email:email}, req.body, function(err,user){
if(err){
throw err;
}
//you do stuff like this
var obj = {
password:'new pass',
username:'username'
}
//use save if you want validate
User.update(user[0],obj,function(err, mod) {
console.log(err)
});
});
Only Update: ( for example using express )
User.update({email:email}, req.body, {}, function(err,user){
if(err){
throw err;
}
res.send(200, {
message : 'User updated ' + user
});
});
Remember that:
A model is a compiled version of the schema.
I hope this can help you

Resources