How to get all records from collection using createddate field in meteor js application - javascript

I have a sample transactions collection similar to below
[
{"_id":"123","createddate":"2017-07-24T09:43:31.028Z"},
{"_id":"124","createddate":"2017-07-25T09:43:31.028Z"},
{"_id":"125","createddate":"2017-07-26T09:43:31.028Z"},
{"_id":"123","createddate":"2017-07-28T09:43:31.028Z"},
{"_id":"126","createddate":"2017-07-27T09:43:31.028Z"}
]
But in my production we have around 50-60 records for each date(createddata field).I need to get all the records for a particular date based on selection then download that.
I used below:
Meteor.methods({
gettransactionsdata:function(){
let transactionRecord = transactions.find({"createddate":"2017-07-26"});
return transactionRecord;
}
});
When I try calling above function it is returning transactionRecord as undefined. How can we do this?

You're storing dates as strings instead of dates which is not recommended for numerous reasons. For a simple day you can do a $regex search to find the strings that begin with the day you're looking for:
transactions.find({ createddate: { $regex: /^2017-07-26/ }});
You could also just pass that date string to your method for a bit more flexibility:
Meteor.methods({
gettransactionsdata(dateStr) {
return transactions.find({ createddate: { $regex: new RegExp('^'+dateStr) }});
}
});

Related

Is there a way to configure the Firestore timestamp outputs?

I'm using Firestore to keep timestamps such as this log output:
{
my_timestamp: Timestamp { seconds: 1676783325, nanoseconds: 209000000 },
product_name: 'Android'
}
I'm reading the values in my web app like this:
...
const result = []
productDocs.forEach((productDoc: DocumentData) => {
result.push({ id: productDoc.id, ...productDoc.data() })
})
return result
...
But I get an error:
Server Error
Error: Error serializing `.productDoc[0].my_timestamp` returned from `getStaticProps` in "/[pid]".
Reason: `object` ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.
It seems to me that the Timestamp object is not easily accepted as part of the object. My solution is to iterate through each Object.entries(productDoc).forEach(productData)... and reformat the Timestamp object and then push on an array.
This seems like a manual way to go about this so I'd like to make sure I'm parsing the timestamp object properly and I'm not missing some way where I can just read the whole result from Firebase as an object with doing nothing to the timestamp.
It seems How do I convert a Firestore date/Timestamp to a JS Date()? is the only way where I have to take the object apart and convert the values.
I didn't see a way to do this on https://firebase.google.com/docs/reference/js/firestore_.timestamp other than just converting the Firebase object.
Using the DocumentSnapshot type should solve your problem:
const result = []
productDocs.forEach((productDoc: DocumentSnapshot) => {
result.push({ id: productDoc.id, ...productDoc.data() })
}
A DocumentSnapshot contains data read from a document in your Firestore database while a DocumentData is to be used with the setDoc() method.

NodeJS MySQL DATE() returns undefined

I'm trying to get Node to query my database and send the results to the client where it is placed into a <table>, but with the timestamp removed from the date.
I have the following bit of Node querying my database:
pool.query(
"SELECT DATE(completed), duration, submitted FROM workentries WHERE iin = ?",[iin],
function(error, results) {
if(error) throw error;
connection.release()
res.send(results);
}
)
The client-side JS:
const httpr = new XMLHttpRequest();
httpr.onload = () => {
let responsej = JSON.parse(httpr.response)
for(i in responsej) {
document.getElementById("workentry-table").innerHTML += "<tr><td>"+responsej[i].completed+"</td><td>"+responsej[i].duration+"</td><td>"+responsej[i].submitted+"</td></tr>";
}
}
httpr.open('GET', '/workentry-list');
httpr.send();
This is the result:
This is how the dates are formatted in the database:
I'm also going to want to reformat the timestamp on the submitted datetime, so it'd be a big help if I can find out how to properly format date/time for this case.
(I'm sorry if this is obvious, but I'm relatively new to Node. I Googled like a madman but couldn't find a solution, which either means this is an uncommon issue or I'm doing something stupid)
EDIT:
Fixed undefined by using DATE(completed) AS completed to the query
Fixed the date/time format by using toLocaleString() in the client-side
You need to give an alias to the column in the SELECT list so you can refer to it as responsej[i].completed. Otherwise, you need to use responsej[i]['DATE(completed)']
And to format it as you want, use the DATE_FORMAT() function rather than returning a DATE.
SELECT DATE_FORMAT(completed, '%Y-%m-%d') AS completed, duration, submitted FROM workentries WHERE iin = ?

I am unable to retrieve data from my mongodb collection and show it to my html page [duplicate]

I have a publication that should return me all users matching an _id array. here it the query:
Meteor.users.find({
'_id': { $in: myArray}},{
'profile.name':1,
'profile.description':1,
'profile.picture':1,
'profile.website':1,
'profile.country':1}
);
When I run it in Robomongo (the mongo browser), it works. But my publication only returns undefined. when I console.log(myArray); in the publication, I get something like this ['FZ78Pr82JPz66Gc3p']. This is what I paste in my working Robomongo query.
Alternative question: how can I have a better feedback(log) from the Collection.find() result?
It looks like you are trying to specify fields in your find, which you can do like this:
var options = {
fields: {
'profile.name': 1,
'profile.description': 1,
'profile.picture': 1,
'profile.website': 1,
'profile.country': 1
}
};
Meteor.users.find({_id: {$in: myArray}}, options);
However, if this is being used in a publish function, I strongly recommend using only top-level fields like so:
Meteor.users.find({_id: {$in: myArray}}, {fields: {profile: 1}});
For more details on why, please see this question.
For your second question, you can view the documents returned by a cursor by calling fetch on it. For example:
console.log(Posts.find({_id: {$in: postIds}}).fetch());

Azure documentdb stored procedure returning partial result

Currently I have got given stored procedure
function getData() {
var context = getContext();
var collection = context.getCollection();
var output = collection.map(function (doc) {
return {
id: doc.id,
name: doc.name,
status: doc.status,
description: doc.description,
owner: doc.owner
}
})
return JSON.stringify(output)
}
Issue here is that it only returs 7 documents (matching what you get when you not get 'load' action on azure panel) and is skipping rest of the collection.
I believe that it can be fixed with using SQL query syntaxt but I would like to know how can I query all documents in the collection without using it.
Try adding a FeedCallback like shown here and make the signature of the callback be function(error, resources, options). Look for errors. Also inspect the options parameter for a continuation. If that fails to give you enough information to fix the problem, then you might want to consider a more traditional query and transformation approach not using collection.map().

Find after populate mongoose

I'm having some trouble querying a document by values matching inside the document after population by mongoose.
My schemas are something like this:
var EmailSchema = new mongoose.Schema({
type: String
});
var UserSchema = new mongoose.Schema({
name: String,
email: [{type:Schema.Types.ObjectId, ref:'Email'}]
});
I would like to have all users which have a email with the type = "Gmail" for example.
The following query returns empty results:
Users.find({'email.type':'Gmail').populate('email').exec( function(err, users)
{
res.json(users);
});
I have had to resort to filtering the results in JS like this:
users = users.filter(function(user)
{
for (var index = 0; index < user.email.length; index++) {
var email = user.email[index];
if(email.type === "Gmail")
{
return true;
}
}
return false;
});
Is there any way to query something like this straight from mongoose?
#Jason Cust explained it pretty well already - in this situation often the best solution is to alter the schema to prevent querying Users by properties of documents stored in separate collection.
Here's the best solution I can think of that will not force you to do that, though (because you said in the comment that you can't).
Users.find().populate({
path: 'email',
match: {
type: 'Gmail'
}
}).exec(function(err, users) {
users = users.filter(function(user) {
return user.email; // return only users with email matching 'type: "Gmail"' query
});
});
What we're doing here is populating only emails matching additional query (match option in .populate() call) - otherwise email field in Users documents will be set to null.
All that's left is .filter on returned users array, like in your original question - only with much simpler, very generic check. As you can see - either the email is there or it isn't.
Mongoose's populate function doesn't execute directly in Mongo. Instead after the initial find query returns a set a documents, populate will create an array of individual find queries on the referenced collection to execute and then merge the results back into the original documents. So essentially your find query is attempting to use a property of the referenced document (which hasn't been fetched yet and therefore is undefined) to filter the original result set.
In this use case it seems more appropriate to store emails as a subdocument array rather than a separate collection to achieve what you want to do. Also, as a general document store design pattern this is one of the use cases that makes sense to store an array as a subdocument: limited size and very few modifications.
Updating your schema to:
var EmailSchema = new mongoose.Schema({
type: String
});
var UserSchema = new mongoose.Schema({
name: String,
email: [EmailSchema]
});
Then the following query should work:
Users.find({'email.type':'Gmail').exec(function(err, users) {
res.json(users);
});
I couldn't find any other solution other than using Aggregate. It will be more troublesome, but we will use Lookup.
{
$lookup:
{
from: <collection to join>,
localField: <field from the input documents>,
foreignField: <field from the documents of the "from" collection>,
as: <output array field>
}
}

Categories