'Querying with mongoose: how to parce a Mongo _id?
I found this similar question to mine, but without explanation Mongoose find query vs $match, I'm trying to do something similar.
I manage to filter by today's date correctly, but I can not yet filter by client's ID.
this works:
var today = new Date(dateTime);
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 1!
var mmd = String(today.getMonth()).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
const filter = {
$match: {
$and: [
{ date: { $gt: new Date(Date.UTC(yyyy, mmd, dd)) } },
// { client: '5f78a00e97f9aa002aa7ec1c' },
{ status: 1 }
]
}
};
// the correct date is whit mmd not mm
const dateSent = new Date(Date.UTC(yyyy, mmd, dd));
console.log(dateSent);
const wpreservationDbagregate = await WorkplaceReservation.aggregate([filter]);
res.json(wpreservationDbagregate);
I got this response, older documents are being correctly filtered:
[
{
"_id": "5f7b93e89d1cb4600e8ce740",
"status": 1,
"workplace": 5,
"date": "2020-10-09T00:00:00.000Z",
"creator": "5f7b36b090b6e518210c6070",
"client": "5f78a00e97f9aa002aa7ec1c",
"userId": "5f7b36b090b6e518210c6070",
"dateCreated": "2020-10-05T21:45:12.229Z",
"__v": 0
},
{
"_id": "5f7b95699d1cb4600e8ce742",
"status": 1,
"workplace": 2,
"date": "2020-10-07T00:00:00.000Z",
"creator": "5f7b36b090b6e518210c6070",
"client": "5f78a00e97f9aa002aa7ec1c",
"userId": "5f7b36b090b6e518210c6070",
"dateCreated": "2020-10-05T21:51:37.219Z",
"__v": 0
}
]
but when tying to filter by client Id it doesnt work, even with the string (it is commented out in the filter constant)
I suppose i have to parse it somehow, but I can find the way...
this is the schema:
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
const workplaceReservationSchema = new Schema({
client: { type: Schema.Types.ObjectId, ref: 'user', required: [true, 'El espacio de trabajo debe ser reservado para algun Cliente'] },
workplace: { type: Number, required: [true, 'El espacio de trabajo es un campo obligatorio'] },
userId: { type: Schema.Types.ObjectId, ref: 'user', required: [true, 'El espacio de trabajo debe ser reservado para algun usuario'] },
creator: { type: Schema.Types.ObjectId, ref: 'user', required: [true, 'Loging incorrecto'] },
date: { type: Date, required: [true, 'La reserva debe tener una fecha'] },
dateModified: { type: Date },
dateCreated: { type: Date, default: Date.now },
status: { type: Number, default: 1 }
});
//Set unique compound indexes
workplaceReservationSchema.index({ workplace: 1, client: 1, date: 1, status: 1 }, { unique: true });
workplaceReservationSchema.index({ userId: 1, client: 1, date: 1, status: 1 }, { unique: true });
const WorkplaceReservation = mongoose.model('workplaceReservation', workplaceReservationSchema);
export default WorkplaceReservation;
package.json:
"dependencies": {
"@babel/cli": "^7.10.4",
"@babel/core": "^7.10.4",
"@babel/node": "^7.10.4",
"@babel/preset-env": "^7.10.4",
"bcrypt": "^4.0.1",
"connect-history-api-fallback": "^1.6.0",
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.10.7",
"mongoose-unique-validator": "^2.0.3",
"morgan": "^1.10.0",
"underscore": "^1.10.2"
}
Solution 1:[1]
Have you tried converting the _id from string to ObjectId ?
Something like { client: mongoose.Types.ObjectId('5f78a00e97f9aa002aa7ec1c') }
Solution 2:[2]
You usually want to keep the variable in the schema for the Object ID implicit (undeclared, let Mongo handle it)
And for your userID and creator variables, use type: String
// Schema
const workplaceReservationSchema = new Schema({
workplace: { type: Number, required: [true, 'El espacio de trabajo es un campo obligatorio'] },
userId: { type: String, ref: 'user', required: [true, 'El espacio de trabajo debe ser reservado para algun usuario'] },
creator: { type: String, ref: 'user', required: [true, 'Loging incorrecto'] },
date: { type: Date, required: [true, 'La reserva debe tener una fecha'] },
dateModified: { type: Date },
dateCreated: { type: Date, default: Date.now },
status: { type: Number, default: 1 }
});
then your query can be structured like this:
const filter = {
$match: {
$and: [
{ date: { $gt: new Date(Date.UTC(yyyy, mmd, dd)) } },
{ _id: '5f78a00e97f9aa002aa7ec1c' },
{ status: 1 }
]
}
};
Solution 3:[3]
I finally finished this query. the main idea was to group by date (that is why i did not use find)
here is the final code:
// Actual GTM -3 DATETIME (Argentina)
const dateTime = new Date(new Date() - 3600 * 1000 * 3).toISOString();
var today = new Date(dateTime);
var dd = String(today.getDate()).padStart(2, '0');
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 1!
var mmd = String(today.getMonth()).padStart(2, '0'); //January is 0!
var yyyy = today.getFullYear();
// Actual GTM -3 Date
today = yyyy + '-' + mm + '-' + dd;
const filter = {
$match: {
$and: [
{ date: { $gt: new Date(Date.UTC(yyyy, mmd, dd)) } },
{ client: mongoose.Types.ObjectId(client) },
{ status: 1 }
]
}
};
const group = {
$group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } },
count: { $sum: 1 }
}
};
const wpreservationDbfiltered = await WorkplaceReservation.aggregate([filter]);
const wpreservationDbgrouped = await WorkplaceReservation.aggregate([filter, group]);
res.status(200).json({ wpreservationDbgrouped, wpreservationDbfiltered });
I got the data grouped by date and also all the documents like this:
{
"wpreservationDbgrouped": [
{
"_id": "2020-10-09",
"count": 1
},
{
"_id": "2020-10-07",
"count": 1
},
{
"_id": "2020-10-08",
"count": 1
}
],
"wpreservationDbfiltered": [
{
"_id": "5f7c87d4670b421d387d2614",
"status": 1,
"workplace": 2,
"date": "2020-10-07T00:00:00.000Z",
"creator": "5f790ad4cb0b41834f94e91b",
"client": "5f78dac286bfd05f21527e49",
"userId": "5f790ad4cb0b41834f94e91b",
"dateCreated": "2020-10-06T15:05:56.258Z",
"__v": 0
},
{
"_id": "5f7c929ed1901826d50af73d",
"status": 1,
"workplace": 3,
"date": "2020-10-08T00:00:00.000Z",
"creator": "5f790ad4cb0b41834f94e91b",
"client": "5f78dac286bfd05f21527e49",
"userId": "5f790ad4cb0b41834f94e91b",
"dateCreated": "2020-10-06T15:51:58.621Z",
"__v": 0
},
{
"_id": "5f7c92a5d1901826d50af73e",
"status": 1,
"workplace": 6,
"date": "2020-10-09T00:00:00.000Z",
"creator": "5f790ad4cb0b41834f94e91b",
"client": "5f78dac286bfd05f21527e49",
"userId": "5f790ad4cb0b41834f94e91b",
"dateCreated": "2020-10-06T15:52:05.373Z",
"__v": 0
}
]
}
thanks a lot for your help!!
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Georgios Kampitakis |
Solution 2 | Stephen Taylor |
Solution 3 | Gaston Campos |