Get all docs by a given date ? (createdAt) - javascript

I have this date given by a date picker widget:
let targetDate = '2019-01-12';
All my documents have a createtAt date generated by timestamps:
"createdAt": "2019-01-12T21:49:05.546Z"
I want to get all documents that field createdAt matches with my given date.
I tried using $elemMatch:
const allDailies = await Daily.find({ createdAt: { $elemMatch: dateTarget } });
const allDailies = await Daily.find({ createdAt: { $elemMatch: { from: dateTarget, to: dateTarget} } });
And no one works, how can I do this query? Actually I can't modify my Schema :(
EDIT:
router.get('/daily/:date', async (req, res) => {
try {
const targetDate = new RegExp(`^${req.params.date}`);
const allDailies = await Daily.find({ createdAt: { $regex: targetDate } });
console.log('Dailies', allDailies);
return res.json({ allDailies });
} catch (error) {
return res.sendStatus(httpStatus.INTERNAL_SERVER_ERROR);
}
});
It returns a 500 error

Convert your targetDate to the same type as createdAt and use it on query as tatgetDate. Not dateTarget as you use it now (you typed it wrong).

You have to convert your target date in to ISODate format. But this will be taken care by mongoose by default so.. What you want to do is change your query like this
Model.find({createdAt:{$gte:params.frm, $lte:params.to}},callback);
or if you want to just give a single date try like this
Model.find({createdAt:dateTarget},callback);

Related

node-oracledb modifies output of a selected timestamp

when i use this the command inside oracle´s sqldeveloper:
SELECT systimestamp FROM dual;
i get an output in this format:
09-DEC-22 12.36.55.179000000 AM -03:00
but when i use the same command with node-oracle-db i get the output in this format:
2022-12-09T04:17:23.545Z
And i would like to get the same kind of output i get using sqldeveloper
this is my code:
const oracledb = require('oracledb')
const dbCredentials = {
user: "user",
password: "password",
connectString: "localhost:1521/xe",
};
async function timeget(dbConfig) {
let connection;
try {
connection = await oracledb.getConnection(dbConfig);
const result = await connection.execute
(
`SELECT systimestamp FROM dual`,
)
console.log(result.rows)
connection.commit();
return res1
} catch (err) {
console.error(err);
} finally {
if (connection) {
try {
await connection.close();
} catch (err) {
console.error(err);
}
}
}
}
timeget(dbcredentials);
Change the SQL statement in your node.js code to output the timestamp as a formatted string:
SELECT TO_CHAR(
SYSTIMESTAMP,
'DD-MON-RR HH12.MI.SS.FF9 AM TZH:TZM',
'NLS_DATE_LANGUAGE=English'
) AS formatted_timestamp
FROM DUAL
Alternatively, read the Node.js documentation on date handling and fetch the timestamp as a string.
The documentation states (I have not tested it) that you can set this before opening the connection:
oracledb.fetchAsString = [ oracledb.DATE ];
to fetch all dates as strings or set the fetch info within the query:
const result = await connection.execute(
'SELECT systimestamp AS time FROM dual',
[],
{fetchInfo: {'TIME': {type: oracledb.STRING}}}
)

Mongoose populate returns empty array or list of ObjectIds

I am practicing my express.js skills by building a relational API and am struggling to populate keys in a schema.
I am building it so I have a list of properties, and those properties have units. The units have a propertyId key.
This is currently returning an empty array, whereas if i remove the populate({}) it returns an array of ObjectIds.
I've read a number of posts and some people solved this by using .populate({path: 'path', model: Model}); but this doesn't seem to be doing the trick. I think it might be the way I am adding a propertyId to the unit but I'm not sure. Can anyone see where I am going wrong? Any help will be massively appreciated.
Here are the schemas.
Property:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const PropertySchema = new Schema({
title: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
},
units: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'unit'
}
]
});
module.exports = Property = mongoose.model('property', PropertySchema);
Unit:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UnitSchema = new Schema({
title: {
type: String,
required: true
},
propertyId: {
type: Schema.Types.ObjectId,
ref: 'property'
}
});
module.exports = Unit = mongoose.model('unit', UnitSchema);
I am then creating the unit like this:
-- api/properties/:id/units --
router.post('/:id/units', async (req, res) => {
// Get fields from req.body
const { title } = req.body;
// Get current property
const property = await Property.findById(req.params.id);
try {
// Throw error if no property
if (!property) {
return res.status(400).json({ msg: 'Property not found' });
}
// Create new unit
const newUnit = new Unit({
title,
propertyId: req.params.id
});
// Add new unit to property's units array
property.units.unshift(newUnit);
// Save property
await property.save();
// Return successful response
return res.status(200).json(property);
} catch (error) {
console.error(error.message);
return res.status(500).send('Server error');
}
});
And trying to populate in the GET request
-- /api/properties/:id/units --
const Unit = require('../../models/Unit');
router.get('/:id/units', async (req, res) => {
const property = await Property.findOne({ _id: req.params.id }).populate({path: 'units', model: Unit});
const propertyUnits = property.units;
return res.status(200).json(propertyUnits);
});
If i remove the .populate({path: 'units', model: Unit});, I get a list of unit id's like this:
[
"5ff7256cda2f5bfc1d2b9108",
"5ff72507acf9b6fb89f0fa4e",
"5ff724e41393c7fb5a667dc8",
"5ff721f35c73daf6d0cb5eff",
"5ff721eb5c73daf6d0cb5efe",
"5ff7215332d302f5ffa67413"
]
I don't know, why you don't try it like this:
await Property.findOne({ _id: req.params.id }).populate('units')
I've been try that code above and it's working.
Note: Make sure to check your req.params.id is not null or undefined and make sure the data you find is not empty in your mongodb.
Updated: I've been try your code and it's working fine.
The issue was caused by inconsistent naming and not saving the new created unit as well as the updated property.
I double checked all my schema exports and references and noticed I was using UpperCase in some instances and LowerCase in others, and saved the newUnit as well as the updated property in the POST request and it worked.

React datetime format not working when sending date as url parameter to API

i am trying to pass date time value as url parameter to backend java api , I am using GET method to send request. But at the api end i am getting only part of date time string, other part of date time string is cutting off.
my react code
const handleStartDate = date => {
setStartDate(date);
const formattedDttm = format(date, "dd.MM.yyyy H:mm:ss", { timeZone: "Asia/Kolkata" });
console.log(formattedDttm);
DataService.findByDttmOfSale(formattedDttm)
.then(response => {
Entry.price = response.data.price;
}).catch(e => {
if (e.response && e.response.data) {
setMessage(e.response.data.message);
setAlertHeading("Error!");
setAlertVariant("danger");
setShow(true);
console.log(e.response.data.message); // some reason error message
}
console.log(e);
});
};
At java backend
#GetMapping("/FromDttmOfSale/{dttm_of_sale}")
public TestMO getFromDateTimeOfSale(#PathVariable(value = "dttm_of_sale") String
dateTimeOfSale) throws Exception {
System.out.println(" get mo from date time of sale date value is = " + dateTimeOfSale);
TestMO testMO = fuelService.getFuelPriceByDateTime(dateTimeOfSale);
return testMO ;
}
the date i entered from react js is of format 11/10/2020 8:42 AM where as at backend i am getting only part of the date string as date time of sale date value is = 11.10
same where during conversion the date string is getting stripped off. i have tried changing the format also but getting same error
Might be better to pass the date as a string and then format it to date on the backend.
i have changed my date param from 11/10/2020 8:42 AM to 11 10 2020 8:42 AM and it started working. seems like there is limitation sending special characters in url
I had the same error and i solved it using two options, first using the moment library and the second that I consider better converting the date toISOString before sending it to the backend.
export async function getAssessmentsByDate(dateInit, dateEnd, clientId) {
try {
const response = await getApi().get(
`/assessment/${clientId}?dateInit=${dateInit.toISOString()}&dateEnd=${dateEnd.toISOString()}`,
{}
);
return response;
} catch (error) {
return { status: 400, message: 'Cant..' };
}
}
In the backend (nodejs) I receive it this way. I recommend you validate the string before using it. It worked perfectly for me.
const getClientAssessmentByDate = async (req, res) => {
try {
const clientId = parseInt(req.params.id);
const dateInit = req.query.dateInit;
const dateEnd = req.query.dateEnd;
/** .... */
/** 3. find evaluations */
const results = await AssessmentResult.findAll({
where: {
createdAt: {
[Op.between]: [dateInit, dateEnd]
}
}
})
/** .... */
} catch (e) {
return res.status(500).send('error processing request');
}
}

Prevent overwriting createdAt and updatedAt in Cloud Function when object set includes them

I'm writing some Node.js code to import data from an existing database into Firebase Cloud Firestore. We have createdAt and updatedAt dates that I want preserved in the transition. The problem is we've created Cloud Functions to automatically set those on object creation, thus it's always overwriting the object's value with the current timestamp. If I run our import script again, thus set is updating the existing document, the createdAt and updatedAt values in the object are preserved.
How can I make it use the specified values and not overwrite them with the current timestamp on create?
const oldNote = {
id: "someid",
text: "sometext",
createdAt: new Date(2018, 11, 24, 10, 33, 30, 0),
updatedAt: new Date(2018, 11, 24, 10, 33, 30, 0)
}
const note = {
text: oldNote.text,
createdAt: firebase.firestore.Timestamp.fromDate(oldNote.createdAt),
updatedAt: firebase.firestore.Timestamp.fromDate(oldNote.updatedAt)
};
firestoredb.collection("notes").doc(oldNote.id).set(note).then((docRef) => {
//FIXME: createdAt and updatedAt aren't preserved, always today
}).catch((error) => {
console.error("Error setting user: ", error);
});
Here's the Cloud Functions:
exports.updateCreatedAt = functions.firestore
.document("{collectionName}/{id}")
.onCreate((snap, context) => {
const now = admin.firestore.FieldValue.serverTimestamp();
return snap.ref.set(
{
createdAt: now,
updatedAt: now
},
{ merge: true }
);
});
exports.updateUpdatedAt = functions.firestore
.document("{collectionName}/{id}")
.onUpdate((change, context) => {
const newValue = change.after.data();
const previousValue = change.before.data();
if (
Boolean(newValue.updatedAt) &&
Boolean(previousValue.updatedAt) &&
newValue.updatedAt.isEqual(previousValue.updatedAt)
) {
const now = admin.firestore.FieldValue.serverTimestamp();
return change.after.ref.set({ updatedAt: now }, { merge: true });
} else {
return false;
}
});
As you can see from the API documentation for Timestamp.fromDate() takes a Date object and converts it to a Timestamp object. However, you're passing it a Timestamp object (unless your edit is faking values that didn't come from the database write in Cloud Functions). This is an unnecessary conversion, and it's likely just returning the current time instead of what you expect. Just use the timestamp values in place:
const note = {
text: oldNote.text,
createdAt: oldNote.createdAt,
updatedAt: oldNote.updatedAt
};
Bear in mind that when you write a Date into Firestore, it stores a Timestamp internally. It's not going to come back out as a Date.
I went ahead and deployed an update to the onCreate trigger in the Google Cloud Console. It now checks if the object already contains createdAt and/or updatedAt and uses them instead of overwriting them if so.
exports.updateCreatedAt = functions.firestore
.document("{collectionName}/{id}")
.onCreate((snap, context) => {
const now = admin.firestore.FieldValue.serverTimestamp();
const createdAt = snap.data().createdAt != undefined ? snap.data().createdAt : now;
const updatedAt = snap.data().updatedAt != undefined ? snap.data().updatedAt : now;
return snap.ref.set(
{
createdAt: createdAt,
updatedAt: updatedAt
},
{ merge: true }
);
});

Query Mongo for all entries added today (newbie)

I'm trying to query Mongo for all entries added today. For example, if I added something at 9 am, I only want that back and not something added at 9 pm last night.
I'm unsure how to properly format the query.
const db = require('../models');
const now = new Date();
const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate());
// Defining methods for the mealsController
module.exports = {
find(req, res) {
db
.Meal
.find({created_on: {$gte: startOfToday}})
},
findAll(req, res) {
db
.Meal
.find(req.query)
.sort({ date: -1 })
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
findById(req, res) {
db
.Meal
.findById(req.params.id)
.then(dbModel => res.json(dbModel))
.catch(err => res.status(422).json(err));
},
I can help you with a precise query if you share how you are storing data in db.
From your question, what i am guessing you are looking for is retrieving documents inserted after a certain time.
ObjectId.getTimestamp() will help you in this case. in Mongo, every insert has a time stamp associated with it. eg. ObjectId("5a6d75590827a11b6016f470").getTimestamp()
returned
ISODate("2018-01-28T07:01:45Z")
To get the Object id of a document, var a = db.collection.find(<condition>).toArray();a[0]._id then prints ObjectId("5a6d75560827a11b6016f46e")
so you can compare which documents were inserted after a certain date or time using this.
GL :)

Categories

Resources