MongoDB count and get the limited data - node.js

I'm trying to get the count all the data for the query and as well as get the limited data (for pagination) but both the console output gives me the count.
What is that I'm doing wrong.
Pls help
const curFind = fbUser.find(find, 'firstName gender age birthday facebookId profileURL email imageUrl preferences blocked flames likes rejects location reported')
curFind.count(function(e, count) {
console.log(count);
curFind.skip(0).limit(10).hint( { $natural : 1 } ).exec(function(err, data) {
console.log(data);
});
});

If you print the curFind object before and after executing count, you will notice that the Query object's op field changes from find to count. It may or may not be a bug with mongoose, but explains why you are getting a count again. I generally don't re-use the query object - which would solve your issue too.

Related

how to save value of formarray in mysql with nodejs

I have a problem and I want someone to help me.
My English is not that good, I'm sorry about that I'll try my best to explain the problem to you hopefully u can help me and thank you.
I'm working on an activity management platform where an employee login to his account and chose a project, then a table contains the days of a certain month under each day there is an input where he enters 1 or 0 if he worked that day or not this is how the UI looks:
When he clicks the button VALIDER (Validate in French) the data entered should be saved in mysql database.
to collect the data I used FormBuilder in angling, I defined as a form group that contains a form control that should get the name of the project, a form control that gets the month, and one for the year, and a form array that should get the values of the 3 inputs, when I console.log the value of the form I get this:
when I try to save the data in my database, I get the message successful, but when I look at my database nothing gets stored,
my database contain a table with :
projectName: varchar(45),
month: number,
year: number,
days: JSON
I think that the problem is that days are an array and not of type Jason because I tried saving an array, but I did like this: insert into project (projectName, days) values ('nomProjet', '['0', '0', '0']') and it gets saved but my days Array doesn't.
my node js code for the backend :
app.post('/cra/add', function (req, res) {
let nomProjet = req.body.projet;
let year = req.body.year;
let month = req.body.month;
let days = req.body.days;
if (nomProjet && year && month && days) {
connection.query('INSERT INTO projetcra2 ( nomProjet, month, year, days ) SET ( ? , ? , ? , ?) ',
[nomProjet, month, year, days],
function (error, results, fields) {
res.send({ status: 'success' , days});
res.end();
});
} else {
res.send({ status: 'failed', message: 'some data are required', loggedin: false });
res.end();
}
});
my formbuilder :
my save function to save to the database :
addDaysWorked() {
this.api.cra(this.form.value).subscribe(
(data: any) => {
console.log(data);
}, (error: HttpErrorResponse) => {
console.log(error);
}
)
}
when i test with postman :
my database :
I hope my problem is explained, if u think I can help with anything else let me know and thank you.
I'm not an expert at backend stuff by any means. However, I believe storing items as an array is inside of a single column in a database is not ideal. You should consider creating a new, separate table, for just days worked.
In the table, you could have a column that specified the date, whether or not he/she worked, and link obviously link this using a foreign key (like userId) to the users table or the main table in this case.
This would allow you to more easily insert the data. Since each day would just be a simple row, querying would also be simpler as you would just query data given a Timeframe (example: from beginning of August - End of August), a user (unique user ID).
Here are a couple other generic stack questions that might clarify as well.
Hope this helps!
Check out this resource as well

firebase functions retrieve data

I have a structure of data like this on firebase
-B4PWzQ84KUOeuTuxVY:{
doctorId:2,
Message:abc
}
I want to retrieve Message on the basis of StudentId there are so many records
my code only retrieve whole object but i need only Messages values wherever doctorId is 2
db.ref('students/' )
.orderByChild("DoctorId")
.equalTo("2")
.once('value',(whereresult) => {
var message = whereresult.val();
});
There are three problems in the code:
Property names are case sensitive, so doctorId <> DoctorId.
You store the ID as a number, so should pass a number to equalTo.
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
In total:
db.ref('students/' )
.orderByChild("doctorId")
.equalTo(2)
.once('value',(snapshot) => {
snapshot.forEach(function(child) {
console.log(child.key, child.val());
});
});

MongoDB/Mongoose returning empty array

I'm currently working on a project with mongodb/mongoose, and every time I purposely query for something that does not exist in the DB, I am getting a response with an empty array. This is my code for using Express to set up an API and return the data found in the DB:
app.get('/api/:id', function(req, res) {
var id = req.params.id;
Job.find({jobID: id}, function (err, foundJob) {
if (err) {
console.log(err);
}
else {
res.json(foundJob);
}
});
});
However, every time I go to localhost:3000/api/67 (I have no object with jobID: 67 in the database yet), the console does not print the error. It gives me a JSON response with an empty array. Any ideas to why this is happening? The weird part is that when I change jobID: id to _id: id, it does give me an error. Why doesn't it do that for the jobID field?
EDIT: Just to clarify, the reason why I do not want this behavior is because my program will never print the error, even if a job in my DB doesn't exist with that specified jobID.
It does something different than you think it does.
Job.find({jobID: id}, ... )
What this really says is give me array with all the documents in collection "Job" that have field "jobID" equal to some value.
What if there is no such document? Well, then the array will be empty. Without any error, of course, what should be an error here? You asked for all documents (given some filter) and an array with all such documents was returned. It is just a coincidence that the size of the array is zero, because there are no such documents.
If you want to check whether there is no such document then check whether the array is empty.
I don't know why it is giving you error when you change JobID to _id; what error exactly is it?
If you are interested only in one document, then there is method findOne that returns only the first document (or null if no such documents exist) instead of an array.
About error when you try to find something by it's __id: It gives you a error because __id is not String, it's ObjectId. So you should search for document with that __id like this: _id: ObjectId(id)
About empty string: If you want to display some kind of different message you should check if db returned something or is it rather empty string that got returned. Something like this:
app.get('/api/:id', function(req, res) {
var id = req.params.id;
Job.find({jobID: id}, function (err, foundJob) {
if(foundJob){
res.json(foundJob);
}else{
res.json("nothing found");
}
if (err) {
console.log(err);
}
});
});
Edit: I didnt realize that you had check for error, I changed code.
Returning an empty string is normal behavior for mongoose. You should handle your response like this:
if (err) {
//handle error
} else if (foundJob) {
//work with your data
} else {
//nothing was found
}
The error you get with _id must be irrelevant and is probably due to an invalid query.

Loopback query which compares field values

Say i have the following Scheme
Product: {
Quantity: Number,
SelledQuantity: Number
}
Would it be possible to write a query where all the results returned are where Quantity=SelledQuantity?
If so, is there a way to use it when doing a populate? (Perhaps inside the match field in the opts object ?)
I use mysql connector.
yes as I understood your problem you can do this by following rest call.
http://localhost:3000/api/products?filter[where][SelledQuantity]=n
this will give you the desired results.
This question is more related to MySQL query. But you can achieve it by javascript as follows:
Product.find({}, fuction(err, products) {
if(err) throw err;
//considering products as array of product. Otherwise you can get to depth for array of product.
var filteredProducts = products.filter(function(p1) {
return p1.Quantity === p1.SelledQuantity;
});
//Your desired output
console.log(filteredProducts);
});
This will be slow but will work for smaller database size. For more optimized answer, ask the question in mysql section with respect to database and table structure.

nodejs: save function in for loop, async troubles

NodeJS + Express, MongoDB + Mongoose
I have a JSON feed where each record has a set of "venue" attributes (things like "venue name" "venue location" "venue phone" etc). I want to create a collection of all venues in the feed -- one instance of each venue, no dupes.
I loop through the JSON and test whether the venue exists in my venue collection. If it doesn't, save it.
jsonObj.events.forEach(function(element, index, array){
Venue.findOne({'name': element.vname}, function(err,doc){
if(doc == null){
var instance = new Venue();
instance.name = element.vname;
instance.location = element.location;
instance.phone = element.vphone;
instance.save();
}
}
}
Desired: A list of all venues (no dupes).
Result: Plenty of dupes in the venue collection.
Basically, the loop created a new Venue record for every record in the JSON feed.
I'm learning Node and its async qualities, so I believe the for loop finishes before even the first save() function finishes -- so the if statement is always checking against an empty collection. Console.logging backs this claim up.
I'm not sure how to rework this so that it performs the desired task. I've tried caolan's async module but I can't get it to help. There's a good chance I'm using incorrectly.
Thanks so much for pointing me in the right direction -- I've searched to no avail. If the async module is the right answer, I'd love your help with how to implement it in this specific case.
Thanks again!
Why not go the other way with it? You didn't say what your persistence layer is, but it looks like mongoose or possibly FastLegS. In either case, you can create a Unique Index on your Name field. Then, you can just try to save anything, and handle the error if it's a unique index violation.
Whatever you do, you must do as #Paul suggests and make a unique index in the database. That's the only way to ensure uniqueness.
But the main problem with your code is that in the instance.save() call, you need a callback that triggers the next iteration, otherwise the database will not have had time to save the new record. It's a race condition. You can solve that problem with caolan's forEachSeries function.
Alternatively, you could get an array of records already in the Venue collection that match an item in your JSON object, then filter the matches out of the object, then iteratively add each item left in the filtered JSON object. This will minimize the number of database operations by not trying to create duplicates in the first place.
Venue.find({'name': { $in: jsonObj.events.map(function(event){ return event.vname; }) }}, function (err, docs){
var existingVnames = docs.map(function(doc){ return doc.name; });
var filteredEvents = jsonObj.events.filter(function(event){
return existingVnames.indexOf(event.vname) === -1;
});
filteredEvents.forEach(function(event){
var venue = new Venue();
venue.name = event.vname;
venue.location = event.location;
venue.phone = event.vphone;
venue.save(function (err){
// Optionally, do some logging here, perhaps.
if (err) return console.error('Something went wrong!');
else return console.log('Successfully created new venue %s', venue.name);
});
});
});

Resources