i'm trying to insert a new document in my Mongo database like this:
MongoClient.connect(MongoURL, function(error, database) {
var collection;
if (error) {
console.log(error);
}
collection = database.collection(job);
collection.insert(json, function(error, result) {
if (error) {
return console.log(error);
} else {
return console.log(result);
}
});
});
And is working, but not like i want.
The 'json' is an array of objects, like this:
json = [
{
"name": "Paulo"
},
{
"name": "José"
}
....
]
So, my code is creating one document for object, and i want create just one document with the objects inside a property called json:
{
json: [
{...},
{...},
{...}
]
}
Is this possible?
I tried to use insertMany, also.
Thanks.
Please try this one,
var obj = {};
obj.json = json;
col.insert(obj, function(error, result) {
if (error) {
return console.log(error);
} else {
return console.log(result);
}
});
Related
I'm trying to display a MongoDB collection of employees into Pug. I know it has something to do with the first 'data' object. I cannot figure out how to render the data within the array.
MongoDB collection:
{
"data":[
{
"active":true,
"userName":"example",
"employeeDetails":{
"personalDetails":{
"firstName":"Dennis",
"lastName":"Glover",
"emailAddress":"example#example.com"
}
}
},
{
"active": false,
"userName": example2,
"employeeDetails": {
"personalDetails": {
"firstName": "Ben",
"lastName": "Dover",
"emailAddress": "example2#example.com"
}
}
},
]
}
Express:
MongoClient.connect(url, function(err, db) {
if (err) {
console.log('Unable to connect to the Server', err);
} else {
console.log('Connection established to', url);
var employeecollection = db.collection('employees');
// Find all employees
employeecollection.find({}).toArray(function(err, employeeResult) {
if (err) {
res.send(err);
} else if (employeeResult.length) {
res.render('employeelist', {
'employeelist': employeeResult,
});
} else {
res.send('No documents found');
}
db.close();
});
};
});
Pug:
table
each employee in employeelist
tr#employee_list_item
td #{employee.userName}
I have fiddled around got it working with Angular2 using ng-repeat, however I cannot seem to get it to render in Pug unless I strip out the 'data' object in the array (which needs to be there).
As much as I can see employeelist[0].data is the array you want to iterate on.
Change employeelist to employeelist[0].data
table
each employee in employeelist[0].data
tr#employee_list_item
td #{employee.userName}
Update. Alternative method:
As Mohit suggested, if you send from the route itself, then your original code will work.
// Find all employees
employeecollection.find({}).toArray(function(err, employeeResult) {
if (err) {
res.send(err);
} else if (employeeResult.length) {
res.render('employeelist', {
'employeelist': employeeResult[0].data,
});
} else {
res.send('No documents found');
}
db.close();
});
Then, in your view:
Pug
table
each employee in employeelist
tr#employee_list_item
td #{employee.userName}
Hope this helps you!
I'm having issues with a simple PUT method in Node.js (MongoDB collection.update). Any help would be appreciated. At this point, I'm not getting an error, just an empty response.
index.js:
app.put('/UpdateValues/:collection/:entity', function(req, res) {
var params = req.params;
var entity = params.entity;
var collection = params.collection;
var value1 = req.body.value1;
var value2 = req.body.value2;
if (entity) {
collectionDriver.updateValues(collection, entity, value1, value2, function(error, objs) {
if (error) { res.status(400).send(error); }
else { res.status(200).send(objs); }
});
} else {
res.send(400, {error: 'bad url', url: req.url});
}
});
collectionDriver.js:
CollectionDriver.prototype.updateValues = function(collectionName, nameDoc, value1new, value2new, callback) {
this.getCollection(collectionName, function(error, the_collection) {
if (error) callback(error);
else {
the_collection.update(
{ name: nameDoc },
{ $set: {
value1: value1new,
value2: value2new
}},
function( err, result ) {
if ( err ) throw err;
}
);
}
});
};
Testing with:
$ curl -i -X PUT -H 'Content-Type: application/json' -d '{"value1":"1","value2":"1"}' http://localhost/UpdateValues/collection/test
Reference the callback you are passing in within your function. Presently you do not. You also seem like you are expeting the modified document in response, so you need .findOneAndUpdate() instead:
CollectionDriver.prototype.updateValues = function(collectionName, nameDoc, value1new, value2new, callback) {
this.getCollection(collectionName, function(error, the_collection) {
if (error) callback(error);
the_collection.findOneAndUpdate( // <-- new method
{ name: nameDoc },
{ $set: {
value1: value1new,
value2: value2new
}},
{ returnOriginal: false }, // <-- tells to return modified document
callback // <--- passes to callback you passed in
);
});
});
I'm a MEAN stack newbie and am attempting to perform multiple updates in a loop using the MongoDB driver for node.js.
When attempting to iterate through the records below via this call, I receive 'Can't set headers after they are sent', presumably because 'next' is called and called again on each subsequen iteration of the loop.
data.sortManual(manualSlug, proposedSortOrder, function(err) {
if (err) {
res.send(400, "Failed to update sort order");
} else {
res.send(200);
}
});
If anybody can help me understand what I'm doing wrong, I'd really appreciate it.
sortManual method below:
manualData.sortManual = function(manualSlug, proposedSortOrder, next) {
database.getDb(function(err, db) {
if (!err) {
var arrSortOrder = proposedSortOrder.split(',');
for (var i = 0; i < arrSortOrder.length; i++) {
arrSortOrder[i] = arrSortOrder[i].replace(/^\s*/, "").replace(/\s*$/, ""); // trim whitespace
db.manuals.findAndModify({
slug: manualSlug,
"topics": {
"$elemMatch": {
"slug": arrSortOrder[i]
}
}
}, [
['_id', 'asc']
], {
$set: {
"topics.$.sort": i
}
}, {
new: false,
upsert: true
}, function(err, result) { <-- I probably shouldn't be doing this on each iteration of the loop but where to handle this?
if (err) {
console.log(err);
next(err, null);
} else {
console.log(result);
next(null, result);
}
});
} // end loop
} // end if
}); // end getDb
}; // end sortManual
It has nothing to do with MongoDB, but the HTTP protocol.
The error message tells you that HTTP headers were set more than once, which is impossible based on Protocol definitions. (Notice: we are talking about response, doesn't matter what inside of Mongo is happening).
The problem lies in callback next (the one which sends headers) is executed multiple times.
If you look into your code, you'll notice there is a for loop, and the next is used as callback in each of the loop steps - thus we have the problem.
Solution
You have to refactor the code to execute next only once, that can be done by basic counting example:
var counter = arrsortOrder.length;
var errors = [];
function checkIfLast(err) {
if(err) {
errors.push(err);
}
counter--;
if(counter == 0) {
if(errors.length > 0)
next(errors.join());
else
next();
}
}
for (var i = 0; i < arrSortOrder.length; i++) {
arrSortOrder[i] = arrSortOrder[i].replace(/^\s*/, "").replace(/\s*$/, ""); // trim whitespace
db.manuals.findAndModify({
slug: manualSlug,
"topics": {
"$elemMatch": {
"slug": arrSortOrder[i]
}
}
}, [
['_id', 'asc']
], {
$set: {
"topics.$.sort": i
}
}, {
new: false,
upsert: true
}, function(err, result) { <-- I probably shouldn't be doing this on each iteration of the loop but where to handle this?
if (err) {
checkIfLast(err);
console.log(err);
next(err, null);
} else {
checkIfLast();
console.log(result);
next(null, result);
}
I have an array of documents with unique _id and I want to insert them to my database. Some of them already in db, and for those I want to update an array property (push in array an item). All of this I need to make asyncronuosly, so after all inserted/updated I want to write response back (with callback) to client than all ok or write an error. After googling on subject I've found this solution with async module I've tried to implement it for my case. Now my code looks like this:
function processUsers(arr, listName, callback) {
var users = global.db.collection('vkusers');
var q = async.queue(function(task, cb) {
console.log('upsert butch');
users.insert(task.doc, function(err, doc) {
if (err) {
users.update({
_id : task.doc._id
}, {
$addToSet : {
mLists : listName
}
}, function(error, result){ console.log(error); console.log(result); });
}
});
}, arr.length);
for ( var doc in arr) {
q.push({
doc : arr[doc]
}, function(err) {
if (err)
callback(err, null);
})
}
q.drain = function() {
// this is the queue's callback, called when the queue is empty,
// i.e. when all your documents have been processed.
console.log('drain');
callback(null, { result: "success", upserted: arr.length });
}
}
Callback has signature callback(error, result), arr - my array of documents. I've tested it and with database everything is OK, i am getting the right result. But callback, and q.drain never fired!
You need to call async.queue's callback (cb in your code) when your insert/update is complete. Something like this:
var q = async.queue(function(task, cb) {
console.log('upsert butch');
users.insert(task.doc, function(err, doc) {
if (err) {
users.update({
_id : task.doc._id
}, {
$addToSet : {
mLists : listName
}
}, function(error, result) {
console.log(error);
console.log(result);
cb(error); // Update finished; call cb and pass in "error" so that it can bubble up if it exists
});
} else {
cb(); // Insert succeeded; call cb
}
});
}, arr.length);
What I try to do is something like this:
A_Schema.statics.init = function init() {
A_Schema.find({}, {}, {
}, function (error, docs) {
if (!error) {
console.log('There is no error.');
}
else {
console.log(error);
}
});
};
I mean, using the find method of the A_Schema model but it keeps crashing.
I suppose that is because the inner A_Schema is must be a properly defined Model and not a Schema, but I don't know how to do it.
I already tried:
A_Schema.statics.init = function init() {
mongoose.model('A_Schema', A_Schema).find({}, {}, {
}, function (error, docs) {
if (!error) {
console.log('There is no error.');
}
else {
console.log(error);
}
});
};
and
A_Schema.statics.init = function init() {
mongoose.model('A_Schema').find({}, {}, {
}, function (error, docs) {
if (!error) {
console.log('There is no error.');
}
else {
console.log(error);
}
});
};
but it keep crashing.
Can you help me?
Thanks in advance
Diosney
Sorry, it seems that I overlook the mongoose documentation.
At mongoose documentation can be see the example:
animalSchema.statics.findByName = function (name, cb) {
this.find({ name: new RegExp(name, 'i') }, cb);
}
So, inside a static the this reference must be used instead of the named model.