Unable to query data with mongoose using dates (nodejs) - javascript

I'm trying to query all Assistance documents that have the "inputDate" between their startDate and endDate. I've been looking on the internet for ages and I'm unable to make it work. It is suposed to retrieve the only document that right now is in my db. I'm using NodeJS+Mongoose.
The code in the controller is the following:
exports.getOccupation = (req, res, next) => {
var inputDate = new Date("1999","10","13","16","0","0");
Assistance.find({
dateInterval:{
startDate: {$lte:inputDate},
endDate: {$gte:inputDate}
}
})
.then(assistances => {
console.log(assistances.length);
})
}
The code of the model:
const assistanceSchema = new Schema(
{
user_id:{
type: Schema.ObjectId
},
place:{
longitude:{
type:String
},
latitude:{
type:String
}
},
dateInterval:{
startDate: Date,
endDate: Date
}
},
{timestamps:true}
);

I'm not sure, but I believe that find() method accept dateInterval.startDate instead of dateInterval:{startDate: ... }.
Try change this way:
Assistance.find({
$and: [
{ "dateInterval.startDate": { $lte: inputDate } },
{ "dateInterval.endDate": { $lte: inputDate } },
],
}).then((assistances) => {
console.log(assistances.length);
});

Related

How to store only certain fields from NeDB database into an array with NodeJS

I have an embedded NeDB database with numerous entries with multiple fields and I'm looking to only get the dates from every entry and store it into an array. I'm using NeDB, NodeJS and express.
The dataset looks like so:
{"goalName":"swim 5km","details":"I want to swim 5km","date":"2021-05-15","completed":false,"author":"somename","_id":"BMnvTm54rNbwc9D4"}
{"goalName":"swim 5km","details":" I want to swim another 5km","date":"2021-03-14","completed":false,"author":"somename","_id":"EwEicEYZAfFxY9Z6"}
{"goalName":"20 pushups","details":"I want to complete 20 full pushups","date":"2021-05-14","completed":false,"author":"anthername","_id":"rP7q6L8jnwGyAgGD"}
I'm only interested in the dates where the author is somename,
I can retrieve these documents using:
getEntriesByUser(userName) {
return new Promise((resolve, reject) => {
this.db.find({ 'author': userName }, function (err, entries) {
if (err) {
reject(err);
} else {
resolve(entries);
console.log('getEntriesByUser returns: ', entries);
}
})
})
}
which then returns the documents where the username = someusername, but i'm only interested in the dates. Preferably storing them to an array with a result like so:
[2021-05-15, 2021-03-14, 2021-05-14]
How would I got about doing this?
Thanks for your help!
You can use the optional second projection parameter of the find() and findOne() methods to include or omit properties of the returned records. see: NeDB#projections.
db.find({ author: userName }, { date: 1, _id: 0 }, function (err, docs) {...});
const
Datastore = Nedb,
db = new Datastore(),
data = [
{ goalName: "swim 5km", details: "I want to swim 5km", date: "2021-05-15", completed: false, author: "somename" },
{ goalName: "swim 5km", details: " I want to swim another 5km", date: "2021-03-14", completed: false, author: "somename" },
{ goalName: "20 pushups", details: "I want to complete 20 full pushups", date: "2021-05-14", completed: false, author: "anthername" },
];
for (const datum of data) {
db.insert(datum);
}
function getEntriesByUser(userName) {
return new Promise((resolve, reject) => {
db.find({ author: userName }, { date: 1, _id: 0 }, function (err, entries) {
if (err) {
reject(err);
} else {
resolve(entries);
console.log('getEntriesByUser returns: ', entries);
}
})
})
}
getEntriesByUser('somename').then((entries) => {
console.log('Mapped return value: ', entries.map(({ date }) => date));
});
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/nedb/1.8.0/nedb.min.js"></script>

Is there a way to make the queries on the Parse Server shorter?

Original Query
const Post = Parse.Object.extend('Post')
const queryPost = new Post()
queryPost.startsWith('title', 'Good Programming')
queryPost.greaterThan('totalLike', 1000)
queryPost.limit(100)
queryPost.include('author')
query.find()
Expected Query
const Post = Parse.Object.extend('Post')
const queryPost = new Post()
queryPost.find({
startsWith: {
title: 'Good Programming'
},
greaterThan: {
totalLike: 1000
},
include: ['post'],
limit: 100
})
The advantage of the method above, I can do the copy and paste as usual when I want to do trials across places.
You can do something like the following but it is not documented:
const query = Parse.Query.fromJSON('ClassName', {
where: {
title: {
'$regex': '^Good Programming'
},
totalLike: {
'$gt': 1000
}
},
include: 'post',
limit: 100
});
query.find();
If you need a JSON version of the query, just run toJSON method to get formatted query as a JSON:
Example
const Post = Parse.Object.extend('Post')
const queryPost = new Post()
queryPost.startsWith('title', 'Good Programming')
queryPost.greaterThan('totalLike', 1000)
queryPost.limit(100)
queryPost.include('author')
queryPost.select(['id', 'name'])
console.log(queryPost.toJSON())
Output
{
where: {
title: {
'$regex': '^\QGood Programming\E'
},
totalLike: {
'$gt': 1000
}
},
include: 'post',
keys: 'id,name',
limit: 100
}
and you can re-execute the above JSON Query using the fromJSON method.
Example
const query = Parse.Query.fromJSON('ClassName', {
where: {
title: {
'$regex': '^Good Programming'
},
totalLike: {
'$gt': 1000
}
},
include: 'post',
keys: 'id,name',
limit: 100
});
query.find();

Mongoose Schema method: Error - model method is not a function

I have two Mongoose model schemas as follows. The LabReport model contains an array of the referenced SoilLab model. There is a static method in the SoilLab model that I was using to select which fields to display when LabReport is retrieved.
//LabReport.js
var mongoose = require("mongoose");
var SoilLab = mongoose.model("SoilLab");
var LabReportSchema = new mongoose.Schema(
{
labFarm: { type: mongoose.Schema.Types.ObjectId, ref: "Farm" },
testName: { type: String },
soilLabs: [{ type: mongoose.Schema.Types.ObjectId, ref: "SoilLab" }],
},
{ timestamps: true, usePushEach: true }
);
LabReportSchema.methods.toLabToJSON = function () {
return {
labReport_id: this._id,
testName: this.testName,
soilLabs: this.soilLabs.SoilToLabJSON(),
};
};
mongoose.model("LabReport", LabReportSchema);
//SoilLab.js
var mongoose = require("mongoose");
var SoilLabSchema = new mongoose.Schema(
{
description: { type: String },
sampleDate: { type: Date },
source: { type: String },
},
{ timestamps: true, usePushEach: true }
);
SoilLabSchema.methods.SoilToLabJSON = function () {
return {
description: this.description,
sampleDate: this.sampleDate,
source: this.source,
};
};
mongoose.model("SoilLab", SoilLabSchema);
When I try to retrieve the LabReport, I get "this.soilLabs.SoilToLabJSON is not a function". This is how I'm trying to retrieve LabReport.
//labReports.js
...
return Promise.all([
LabReport.find()
.populate("soilLabs")
.exec(),
LabReport.count(query).exec(),
req.payload ? User.findById(req.payload.id) : null,
]).then(function (results) {
var labReports = results[0];
var labReportsCount = results[1];
var user = results[2];
return res.json({
labReports: labReports.map(function (labReport) {
return labReport.toLabToJSON(user); //This cant find SoilToLabJSON
}),
If I remove the .SoilToLabJSON in LabReport.js and just call this.soilLabs, it works but outputs all of the soilLabs data which will become an issue when I have the model completed with more data. I have dug into statics vs methods a little and tried changing it to statics but it didn't work.
I get the soilLabs to populate but not sure why the .SoilToLabJSON method is inaccessible at this point. Do I need to find() or populate the soilLab differently? Is the method incorrect?
labReport.toLabToJSON is passing an array and that was causing the error for me. I simply edited the LabReport.js to the following to take the array and map it to SoilToLabJSON properly.
myTestSoilLabOutput = function (soilLabs) {
var test = soilLabs.map(function (soilLab) {
return soilLab.SoilToLabJSON();
});
return test;
Changed the LabReportSchema.methods.toLabToJSON to:
LabReportSchema.methods.toLabToJSON = function () {
return {
labReport_id: this._id,
testName: this.testName,
soilLabs: myTestSoilLabOutput(this.soilLabs),
};
};

Moment not working for winston.transports.File

From the below post i got the idea to use moment with winston to change date format.
winston:how to change timestamp format
but this is working for winston.transports.Console and its not working for winston.transports.File
PFB my code :
var logger = new winston.Logger({
level: 'debug',
timestamp: function () {
return moment().format('YYYY-MM-DD hh:mm:ss')
},
transports: [
new(winston.transports.MongoDB)({
db : 'dbpath',
collection : 'Logs',
level : 'error',
capped : true,
timestamp: function () {
return moment().format('YYYY-MM-DD hh:mm:ss')
}
}),
new winston.Logger({
level: 'debug',
transports: [
new(winston.transports.File)
({ filename: 'filename' })
],
timestamp: function () {
return moment().format('YYYY-MM-DD hh:mm:ss')
}
}),
new winston.transports.Console({
timestamp: function () {
return moment().format('YYYY-MM-DD hh:mm:ss')
}
})
]
})
I am getting this in my output file:
{"level":"info","message":"info Hello","timestamp":"2018-04-16T06:42:12.819Z"}
{"level":"error","message":"error Hello","timestamp":"2018-04-16T06:42:12.847Z"}
{"level":"debug","message":"debug Hello","timestamp":"2018-04-16T06:42:12.861Z"}
{"level":"warn","message":"debug Hello","timestamp":"2018-04-16T06:42:12.900Z"}
it's neither working for mongodb transport

Add more fields in MapReduce with Mongoose and NodeJS

I've this mongoose schema
var SessionSchema = mongoose.Schema({
id: Number,
cure: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Cure'
},
performances: Array,
startDate: Date,
endDate: Date,
validatee: Boolean,
deleted: Boolean
});
I need to know how many documents have different ids, but i only need those that have startDate greater than a given date (for example today).
Running the following code works fine but i want to add some fields in map to use them in the query.
var o = {};
o.map = function () {
emit(this.id, 1
// list other fields like above to select them
)
}
o.reduce = function (k, vals) {
return vals.length
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime)
console.log("MapReduce" + JSON.stringify(model));
model.find().exec(function (err, docs) {
console.log(docs);
});
});
This is my output :
[ { _id: 0, value: 2 },
{ _id: 1, value: 4 },
{ _id: 2, value: 2 } ]
I try to do this:
....
o.map = function () {
emit(this.id, {
startDate: this.startDate
})
}
....
model.find({
startDate: {
"$gte": new Date()
}
}).exec(function (err, docs) {
console.log(docs);
});
....
but I keep getting the same output.
So how do I add more key-value params from the map function to the result dictionary of the reduce function?
This is a solution :
var o = {};
o.map = function () {
emit(this.id, {
startDate: this.startDate,
cure: this.cure,
test: 'test'
// list other fields like above to select them
})
}
o.reduce = function (k, vals) {
return {
n: vals.length,
startDate: vals[0].startDate,
cure: vals[0].cure,
test: vals[0].test
}
}
o.out = {
replace: 'createdCollectionNameForResults'
};
o.verbose = true;
Session.mapReduce(o, function (err, model, stats) {
console.log('map reduce took %d ms', stats.processtime);
model.find({
'value.cure':mongoose.Types.ObjectId('52aedc805871871a32000004'),
'value.startDate': {
"$gte": new Date()
}
}).exec(function (err, docs) {
if(!err)
console.log(docs.length);
});
});

Categories

Resources