mongoose, getting object's id after using collection.insert - node.js

I'm trying to get the object id after adding it to the db (using collection.insert)
mongoose.model('Persons').collection.insert(person, function(err, newPerson) {
console.log('lets see you', newPerson);
});
and from the console I'm getting only result: { ok: 1, n: 1 } in stand of the new obj, any ideas how can I rich to the new object ?
thanks!

You can use save() here
var Persons = mongoose.model('Persons');
var personJSON = {
..... // persons schema values you want to insert
};
var person = new Persons(personJSON);
var result = yield person.save();
result variable will contain all the fields you inserted along with _id

Related

How to search data in mongodb with dynamic fields using mongoose?

I've a node.js api in which user sends the required fields as an array to be fetched from the mongodb database. I need to find the data of that fields using Find query. I've written forEach statement to loop through that array and got the array elements. But when I try to get the results by inserting the array elements in the query, it doesn't giving the required results. Could any one please help me in resolving the issue by seeing the code below?
templateLevelGraphData: async function(tid,payload){
let err, templateData, respData = [], test, currentValue;
[err,templateData] = await to(Template.findById(tid));
var templateId = templateData.templateId;
payload.variables.forEach(async data=>{
console.log(data); //data has the array elements like variables=["humidity"]
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({},{data:1}).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue);
});
return "success";
}
The expected output is,
[ { humidity: 36 } ]
But I'm getting only _id like,
[ { _id: 5dce3a2df89ab63ee4d95495 } ]
I think data is not applying in the query. But I'm printing the data in the console where it's giving the correct results by displaying the array elements like, humidity. What I need to do to make it work?
When you are passing {data: 1} you are passing an array where is expecting name of column.
You have to create an object where the keys are going to be the elements of the array and set them to 1.
const projection = data.reduce((a,b) => (a[b]=1, a), {});
[...] .find({}, projection) [...]
Actually I got the solution.
for(let i=0;i<payload.variables.length;i++){
var test = '{"'+ payload.variables[i] +'":1,"_id":0}';
var query = JSON.parse(test);
[err, currentValue] = await to(mongoose.connection.db.collection(templateId).find({"deviceId":deviceId},query).sort({"entryDayTime":-1}).limit(1).toArray());
console.log(currentValue); //It's giving the solution
}

Update mongodb document, if the document exists, else create

So I am trying to make a discord bot for me and my friends for tracking stats in CS GO 10 mans, and I am using cheerio for webscraping from the site that provides us the stats, and then pass them into mongodb. The scraping functionality works fine, but im trying to figure out how to avoid creating duplicate documents for each user. If I enter *userid 857575 it pulls the stats for that user, and puts in the DB, but if i call that multiple times, its making multiple documents in the DB. My question is, how would I get mongodb to update the document based on if the message author in discord matches the username in the db? So if username bob sends *userid3939 and bob already exists in the db, update the document. If bob doesnt exist, create document. code below, appreciate any tips.
module.exports.run = async (bot, message, args) => {
console.log(args);
var userUrl = 'https://popflash.site/user/' +args;
console.log(userUrl);
console.log(message.member.user.tag);
rp(userUrl)
.then(function (html) {
const arr = [];
var i = 0;
$('.stat-container', html).each(function (key, value) {
arr[i++] = $(this).find(".stat").text();
});
const stats = new Stats({
_id: mongoose.Types.ObjectId(),
userName: message.member.user.tag,
userId: args,
HLTV: arr[0],
ADR: arr[1],
HS: arr[2],
W: arr[3],
L: arr[4],
T: arr[5],
win_percent: arr[6]
});
stats.save()
.then(function (result) {
let botembed = new Discord.RichEmbed()
.setDescription(message.member.user + "'s 10 Man stats")
.setColor("#15f153")
.addField("stats", result)
return message.channel.send(botembed);
})
})
}
module.exports.help = {
name: "userid"
}
Through db.collection.update, you can specify the upsert: true option to get the behavior I think you're desiring. It will update an existing record if matched, otherwise it will create a new record.

MongoDB: How to get timestamp and ObjectID from newest document in collection?

I would like to get last created documents in collection and return their objectID and timestamps. For example if yesterday I created 10 documents I would like to return them with db.collection and then
const lastTimeStamp = will be the timestamp from the last created element
const lastTimeStampArray = will be array of timestamps from yesterdays records
const lastObjectId = will be ObjectID of last created document
const lastObjectIdsArray = array of last objectIds
I am using:
MongoDB's _id field has info about date stored in itself. The timestamp is contained in the first 4 bytes of a mongoDB id.
You can use ObjectId.getTimestamp() function to get time from _id of a document.
Sorting on an _id field that stores ObjectId values is roughly equivalent to sorting by creation time.
For you question:
// To get lastTimeStamp
db.collection.find().sort({ '_id': -1}).limit(1).forEach(
function(doc){
lastTimeStamp = doc._id.getTimestamp();
}
)
// to get lastObjectId
db.collection.find().sort({ '_id': -1}).limit(1).forEach(
function(doc){
lastObjectId = doc._id;
}
)
Now, to get all records inserted yesterday might be a bit of hard work. You need to extract all records inserted yesterday and from that you need to extract information you need.
// to get lastTimeStampArray and lastObjectIdsArray
var yesterdayStart = new Date();
yesterdayStart.setDate(yesterdayStart.getDate() - 1);
yesterdayStart.setHours(0,0,0,0);
var startId = Math.floor(yesterdayStart.getTime() / 1000).toString(16) + "0000000000000000";
var yesterdayEnd = new Date();
yesterdayEnd.setDate(yesterdayEnd.getDate() - 1);
yesterdayEnd.setHours(23,59,59,999);
var endId = Math.floor(yesterdayEnd.getTime() / 1000).toString(16) + "0000000000000000";
var lastTimeStampArray = [];
var lastObjectIdsArray = [];
db.collection("records")
.find( { _id: {
$gte: ObjectId(startId),
$lte: ObjectId(endId)
}
}
).forEach(
function(doc){
lastObjectIdsArray.push(doc._id);
lastTimeStampArray.push(doc._id.getTimestamp());
});
These are mongo shell commands you can write your node.js accordingly.
You can get last inserted record with timestamp using the following:
db.collection.find().sort({ '_id': -1 }).limit(1).forEach(
function(doc){
print("record:"+doc._id.getTimestamp());
})
_id is the Mongodb objectID

Inserting into array error in Mongoose

This is my MongoDB schema, Seems like push operator is not working
locationCoordinate : {
type : [Number],
index: '2d'
},
i am getting Post data from frontend in my Node.js server which is having Longitude and Latitude
var event = new Events({})
(Events is the name of Schema )
I want to push into this array,
so this seems not to be working
Error on this line
event.locationCoordinate.push(req.body.longitude);
event.locationCoordinate.push(req.body.latitude);
And then saving this by
event.save(function(err,result)){
}
The result may be something like
locationCoordinate[1,2]
var array = [];
array.push({"lng":req.body.longitude},{"lat":req.body.latitude}); // or
array.push(req.body.longitude,req.body.latitude); //just try mybe work
var Evnt = new Events()
Evnt.type = array;
Evnt.index = req.body.index;
Evnt.save(function(...){ ... });

NodeJS Module Pattern

I'm about to begin writing a new module for a system I'm developing. We use a MySQL database (so I'm using node-mysql) which contains a customers table.
What I want to achieve is:
Outside of the module I'm looking to do var C = new Customer(1) where 1 is the customer ID.
Now when I want to get something from this customer, I can do C.email or C.first_name which will simply return a value.
I also need to be able to set values back on this customer, C.email = 'example#example.com' or perhaps:
C.set('email', 'example#example.com')
What would be the best pattern to create such a model?
I already have something like this... Not exactly what you demanded but very close to that
I have generalized the core part and here is the code..Hope this will help....
var mysql = require('mysql');
var con = mysql.createConnection({
host:"yourHostName",
user:"yourUserName",
password:"yourPassword"
});
con.query("use databaseName");
function getCustomerDetails(custId){
con.query("select * from customer where custId = "+custId,function(err,result,fields){
if(!err)
return result;
else
console.log(err);
});
}
function updateCustomerDetails(custId,fieldName,fieldValue){
con.query("update customer set "+fieldName+" = "+fieldValue+" where custId = "+custId,function(err,result,fields){
if(!err)
return true;
else
console.log(err);
return false;
});
}
exports.getCustomerDetails = getCustomerDetails;
exports.updateCustomerDetails = updateCustomerDetails;
And then suppose you saved the module as dbAccessModule.js Then you can use the functions like this
var C = require('./dbAccessModule');
result = C.getCustomerDetails(1);
console.log(result.fieldName);
var success = C.updateCustomerDetails(1,'name','sumit');
if(success)
console.log('Table Updated successfully....');
else
// take necessary action according to your application
One thing you need to take care of is that if you are updating any field with string value
then please don't forget to surround the value of fieldValue with single quotes.
If this is not what you asked for then please ignore it....
I recently created two database modules you might be interested in checking out to see if they fit your needs - an ORM: http://bookshelfjs.org and Query Builder: http://knexjs.org
The ORM is based off of the design patterns of Backbone.js
So, you'd be able to do something like this:
// Create the base customer object
var Customer = Bookshelf.Model.extend({
tableName: 'customers'
});
// Create a new customer instance with an id of 1, fetch it, and then
// act on the result model 'customer'.
new Customer({id: 1}).fetch().then(function(customer) {
console.log(customer.get('name'))
customer.set('email', 'email#example.com')
return customer.save();
});
You could also extend the base Customer class to enable a shortened syntax, similar to what you're looking for:
// Create the base customer object, with a static findOne method.
var Customer = Bookshelf.Model.extend({
tableName: 'customers'
}, {
find: function(id) {
return new this({id: id}).fetch();
}
});
Customer.find(1).then(function(C) {
console.log(C.get('name'))
C.set('email', 'email#example.com')
});

Resources