Firebase query not applying "where" - node.js

Im trying to do a multiple filter system. So I need to be able to add a "where" depending the filters that I got.
When I try to add the "where" like this, the snapshot has the correct houses.
const houses = db
.collection("Houses")
.where("ventRent", "==", "Sell")
.limit(paginaSize);
const snapshot = await houses.get();
But when I try to add the "where" like this, the snapshot has every house, as if it didn't do the "where".
const houses = db
.collection("Houses")
.limit(paginaSize);
if(filters) {
if(filters.selectCR) {
if(filters.selectCR === "Selling") {
houses.where("ventRent", "==", "Sell");
} else {
houses.where('ventRent', '==', "Rent");
}
}
}
const snapshot = await houses.get();
I've tried changing to let, var and const and nothing. I've change the '' to "" or vice versa and nothing too.
I think Im doing it in the correct way, but I have no idea why is not working

Every time you call where it returns a new query. So you have to assign the result of houses.where(...) to a variable, typically back to `houses.
So for example:
houses = houses.where("ventRent", "==", "Sell");
Then at the end when you call houses.get(), you're calling it on the completed query.

Related

How to query by date on cloud function?

I'm trying to query some data that is between two dates, but nothing seems to work. These are my dates, I saw on a post that the division by 1000 should work , but it's not. Ive tried firebase.firestore but says firebase it's not defined but I don't know how to simply reference to firebase.firestore.Timestamp
let now = new Date()
let yesterday = Math.round((new Date(now.getFullYear(), now.getMonth(), now.getDate() - 1).getTime())/1000)
now = Math.round(now.getTime()/1000)
This is my query attempt. Nothing works and it just returns my empty array because the query has no data to iterate through the forEach.
let snapshot = await db.collection('appointments')
.where('status', '==', 'Pending')
.where('startDate', '<=', now)
.where('startDate', '>', yesterday)
.get().then(docs => {
docs.forEach(snapshot => {
console.log(snapshot.id, '=>', snapshot.data());
console.log(snapshot.data()['doctor']);
doctor_mail.push(snapshot.id)
doctor_mail.push(snapshot.data())
});
return doctor_mail
}).
catch(err => {
return res.send(err)
});
console.log(doctor_mail)
res.send(snapshot)
The query is not returning anything because there is nothing to return. If you are querying for a string representing a date and the data is a timestamp in the Firestore, so in order to know that, it would be need to check a sample document to compare, since in the first part of your question you mentioned that you want to get a Firestore timestamp, you can do it with this code:
const timestamp = db.FieldValue.serverTimestamp();
//if you want it as a date object
const date = timestamp.toDate();
As per what you asked in the comments, for getting the value of Today and Yesterday in Timestamp you can do the following:
var todayTimestamp = timestamp.now();
var date = new Date().setDate(date.getDate() - 1);
var yesterdayTimestamp = timestamp.fromDate(date);
And convert them back to date so you can operate them if needed, you can check more details on the Timestamp in this Documentation
Okay, the thing here was that I was wrongly calling db as const db = firebase.firestore.
Instead I just had to go for:
const db = admin.firestore()

Can't use variables as key, value for mongoose .find()

I'm using mongoose 5.11.4 and trying to find documents. On the official docs they say
MyModel.find({ name: /john/i })
I wanna know how to use variables for "name" & "john" and get the exact thing done. this is an API that I'm working on. filter (name) and the value (john) gonna decide by the frontend user. We should search for a given field using the value. Any suggestions?
let filter = req.params.filter
let value = req.params.value
MyModel.find({ filter : /value/i })
doesn't work
You can use the RegExp object to convert the value to a regular expression.
let regex = new RegExp(`${value}`,'options');
Now you can use it on mongoose query.
model.find({name:regex});
this worked : )
let filter = req.params.filter
let value = req.params.value
const filterParam = {}
filterParam[filter] = { $regex: .*${value}.* }
const suppliers = await Supplier.find(filterParam)

Mongoose, NodeJS & Express: Sorting by column given by api call

I'm currently writing a small API for a cooking app. I have a Recipe model and would like to implement sorting by columns based on the req Parameter given.
I'd like to sort by whatever is passed in the api call. the select parameter works perfectly fine, I can select the columns to be displayed but when I try to sort anything (let's say by rating) the return does sort but I'm not sure what it does sort by.
The code i'm using:
query = Recipe.find(JSON.parse(queryStr));
if(req.query.select){
const fields = req.query.select.split(',').join(' ');
query = query.select(fields);
}
if(req.query.sort){
const sortBy = req.query.sort.split(',').join(' ');
query = query.sort({ sortBy: 1 });
} else {
query = query.sort({ _id: -1 });
}
The result, when no sorting is set: https://pastebin.com/rPLv8n5s
vs. the result when I pass &sort=rating: https://pastebin.com/7eYwAvQf
also, when sorting my name the result is also mixed up.
You are not using the value of sortBy but the string "sortBy". You will need to create an object that has the rating as an object key.
You need the sorting object to look like this.
{
rating: 1
}
You can use something like this so it will be dynamic.
if(req.query.sort){
const sortByKey = req.query.sort.split(',').join(' ');
const sortByObj = {};
sortByObj[sortByKey] = 1; // <-- using sortBy as the key
query = query.sort(sortByObj);
} else {
query = query.sort({ _id: -1 });
}

NodeJS/Mongoose - How to reference individual models after concatenation?

I am concatenating two models (Blogs and Events) so I can display all records from both collections in a single forEach loop:
const blogs = await Blog.find({});
const events = await Event.find({});
const blogsAndEvents = blogs.concat(events);
blogsAndEvents.forEach(function(blogOrEvent) { etc. etc.
However, within the forEach loop, in some cases, I want to still reference the original model it comes from, e.g. 'if Blog, title equals BLOG, if Event, title equals event). I have a workaround for this where I am using a unique field from each model to determine the underlying model, like this:
if (blogOrEvent.blogPost) {
title = "BLOG"
} elseIf (blogOrEvent.eventDate) {
title = "EVENT"
}
This approach doesn't seem very clean to me though as it relies on their being a unique field in each model. It there a better way I can access the original underlying model within the loop? Thanks.
With mongoose documents it can be distinctly verified which Model they belong to using instance of :
const blogs = await Blog.find({});
const events = await Event.find({});
const blogsAndEvents = blogs.concat(events);
blogsAndEvents.forEach(function (blogOrEvent) {
if (blogOrEvent instanceof Blog) {
title = "BLOG";
} else if (blogOrEvent instanceof Event) {
title = "EVENT";
}
});

how to pass fieldname dynamically in mogodb

I want to pass field name dynamically in Mondgodb while query the collection. e.g.
emp.ply = function(res,res) {
Employee.find({area: 'Plymouth'}).exec(function(err,PLY) {
res.render("../index", {resultset: PLY})
here I'm doing query on field name area which is hard code. Instead of i want to pass fieldname dynamically. How we can achieve it in nodeJS
So, conceptually you just need to build the query object before sending it to the .find() function. Perhaps something like this:
const query = {}
const fieldname = 'area'
const fieldvalue = 'Plymouth'
query[fieldname] = fieldvalue
Employee.find(query).exec((err, ply) => {
// do whatever
});
You could conceptually extract both fieldname and fielvalue from req.body or req.query depending on what you're doing.
If your code supports ES6 or (any latest browser except IE), we can do this:
emp.ply = function(res,res) {
let searchField = 'area'; // this can be anything dynamically
Employee.find({[searchField]: 'Plymouth'}).exec(function(err,PLY) {
res.render("../index", {resultset: PLY})
})
}
You can refer to MDN docs about Computed property names

Resources