Get documents from firestore based on timestamp field - node.js

I am trying to get all the documents with a dateStart timestamp field that is less than 24 hours in the future using a collectionGroup query. However, it would not be ideal to get all documents and test it for each document, as the documents can accumulate over time.
I have tried to do the following, but it gives an error:
const currentDate = moment();
const snap = db.collectionGroup('appointments').where(moment.duration(currentDate.diff(moment(new Date('dateStart')))).asHours() < 25).get()
.then(function(querySnapshot){
querySnapshot.forEach(function(doc){
console.log(doc.id);
});
});
The error I am getting is the following:
Error: Value for argument "fieldPath" is not a valid field path. Paths can only be specified as strings or via a FieldPath object.
I am not sure if it is even possible to add logic like this in the where clause of the query, or if I am just doing this the wrong way. I am currently using the moment library, but this isn't mandatory for the solution. I do think it is the easiest way to get the difference between date objects.
Does anyone have an idea to get this done without looping through all the documents in the collection?

You are doing something very wired.
The where function should be:
.where('dateStart', '<', next24HoursDate)
So try something like this:
const next24HoursDate = moment(new Date()).add(24, 'hours');
const snap = db.collectionGroup('appointments')
.where('dateStart', '<', next24HoursDate)
.get()
.then( function(querySnapshot) {
querySnapshot.forEach( function(doc) {
console.log(doc.id);
});
});

Related

How to pass date as an input to SQL Server query in node

I am using node-mssql and my function goes like this:
const getPoliciesDue = async (userId, toDate) => {
const db = await sql.connect(config) // const sql = require('mssql'), config = {config for my DB}
const request = db.request()
.input('userId', sql.VarChar, userId) // userId is a string
.input('toDate', sql.Date, toDate) // toDate is a javascript Date() object
const result = await request.query(
'SELECT policyNumber, holderId, ... FROM Policies WHERE Policies.userId = #userId AND Policies.toDate <= #toDate'
)
return result.recordset
}
I want to get all the policies which are expiring before a certain date belonging to a certain user.
But when I run this exact query, I get the error
Must declare the scalar variable #userId
I removed #userId from the WHERE clause and put '#toDate' (quotes around the variable). Now I get an error
Conversion failed when converting date and/or time from character string
The documentation says input() accepts the Date() object. I have tried passing date object as well as a string in YYYY-MM-DD format, but with no avail. Passing a string in YYYY-MM-DD format works for an INSERT query, but not for a SELECT query. How am I supposed to run my query?
Note I can't run the query in a single line, like
db.request().input().query()
because there is another input which will later go in conditionally.
Okay, a huge oversight on my part and sincere apologies to those who tried to find an answer. I found out that I was running the query() method on the wrong object. I was running the query method on db object whereas I should have run it on the request object. The code works perfectly after calling the method on the right object.

How can I limit the result to a field with array that has a specific value?

I want to display a single article only with those comments (it is an array) which have the approve value set to "true" in my database. I can't get the correct result. Here is my backend code. I use pure MongoDB, without Mongoose.
app.get("/posts/:id", function (req,res) {
blog.collection("posts").findOne({"_id":ObjectId(req.params.id)}
,function (error,post )
{
res.render("user/post",{post:post});
});
});
Here is what my database looks like, I want to filter or limit the result to comment approve = "true".
Thank you very much for every answer.
I don't know if there is better solution but it can be obtained by this:
let newPost = {...post}
newPost.comments = newPost.comments.filter(comment=>comment.approve)
res.render("user/post",{post:newPost});

Sails.js: How to find records based on values in associated collection?

I'm looking for a way to make sub-query using Sails.js Waterline. The record has an association with Charge model.
I would expect something like that to work, but that doesn't seem to be supported:
var topRecords = await Record.find({'charge.paid':true});
The closest I got was this:
var topRecords = await Record.find().populate('charge',{paid:true});
but the problem is that it still returns all the Records regardless, just doesn't populate the records that do not match populate where statement.
The reason why I can't search for charges first is that I want to sort the data based on one of the values in Record.
You can fetch the Charges then use .map to get the records from there.
const topCharges = await Charge.find({ paid: true }).populate('records');
const topRecords = topCharges.map(charge => charge.record);

How to actually query data from Firestore with GeoFirestore?

I'm trying to query documents near a given point in given radius in Firestore with using GeoFirestore for my node.js project. Firstly, I have a document in the database in this format:
My query code is like this:
// Create the GeoFirestoreQuery object
const geoQuery = geoFirestore.query({
center: new firebase.firestore.GeoPoint(latitute, longitude),
radius: 5,
query: (ref) => ref.where("d.available", "==", true)
});
The thing is that, I cannot figure out how to get the document from the query. I tried the code below, but it simply is not called at all.
// Fetch the nearest couriers
const onKeyEnteredRegistiration = geoQuery.on("key_entered", function(key, document, distance) {
console.log(key);
});
How can I return the document? What I am missing? Is my query and database structure matches? Is there any missing fields or issues? Or should I use another query instead of "key_entered"? Thanks for any help in advance.
I found the issue, it was about the database structure. I changed my structure as shown below and now it works perfectly.

mongoose: how to get string representation of query

I implementing module who automatically generate mongoose query by requested params, so for simplified test process I need to be able to get text representation of final query. How could I do that?
Like we have something like this:
var q = AppModel.find({id:777}).sort({date:-1})
I need to get something like this
"db.appmodels.where({id:777}).sort({date: -1})"
You can set debug for mongoose, which would by default send the queries to console, to use the following:
mongoose.set('debug', function (collectionName, method, query, doc) {
// Here query is what you are looking for.
// so whatever you want to do with the query
// would be done in here
})
Given a query object q you can rebuild the query using its fields, namely q._conditions and q._update. This is undocumented though and could easily break between versions of Mongoose (tested on Mongoose 4.0.4).

Resources