Closed Here21 closed 2 years ago
is user_id in your schema of Schema.Types.ObjectId?
@Uzlopak yep~it seems to be mongoose doesn't trans Date to ISODate...
@Uzlopak full filter like is:
const filter = {
user_id: new Types.ObjectId(props.user_id),
status: props.status,
created_at: undefined,
};
if (props.date) {
// filter.created_at = {
// $gte: dayjs(props.date).startOf('date').toISOString(),
// $lte: dayjs(props.date).endOf('date').toISOString(),
// };
filter.created_at = {
$gte: new Date(2022, 0, 21),
$lte: new Date(2022, 0, 24),
};
}
What is you Schema?
@Uzlopak full schema here:
import { Schema, Types, HydratedDocument } from 'mongoose';
import { TrainingExerciseConfigSchema } from '../common/common.schema';
import { ExecuteStatus } from '../common/common.interface';
import { TrainingLog } from './tl.interface';
import { TrackDataSchema } from '@src/models/training/training.schema';
export const TrainingLogExerciseSchema = new Schema({
exercise_id: {
type: Types.ObjectId,
ref: 'Exercise',
required: false,
},
name: String,
thumb: String,
track_type: String,
default_track_data: [TrackDataSchema],
track_data: [TrackDataSchema],
config: TrainingExerciseConfigSchema,
});
export const ModelName = 'TrainingLog';
export type TrainingLogDocument = HydratedDocument<TrainingLog> & Document;
export const TrainingLogSchema = new Schema<TrainingLog>(
{
user_id: { type: Types.ObjectId, ref: 'User' },
routine_id: {
type: Types.ObjectId,
ref: 'Routine',
},
training_id: {
type: Types.ObjectId,
ref: 'Training',
require: true,
},
name: { type: String, required: true },
desc: String,
exercises: {
type: [TrainingLogExerciseSchema],
default: [],
},
duration: {
type: Number,
default: 0,
},
comment: String,
status: {
type: String,
enum: ExecuteStatus,
default: ExecuteStatus.DOING,
},
del: { type: Boolean, default: false },
},
{
timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' },
collection: 'training_log',
},
);
Try to replace Types.ObjectId with Schema.Types.ObjectId. I have the feeling, it gets converted to String and thats why you find nothing.
https://mongoosejs.com/docs/schematypes.html#what-is-a-schematype
@Uzlopak thanks for help, It doesn't seem to be caused by this problem, even I remove user_id
on the filter field, still got nothing:
const filter = {
status: props.status,
created_at: undefined,
};
if (props.date) {
// filter.created_at = {
// $gte: dayjs(props.date).startOf('date').toISOString(),
// $lte: dayjs(props.date).endOf('date').toISOString(),
// };
filter.created_at = {
$gte: new Date(2022, 0, 21),
$lte: new Date(2022, 0, 24),
};
}
logger.debug('findAll:', JSON.stringify(filter));
return this.trainingLog.find(filter);
So, I think the problem at Schema.options.timestamps or mongoose date type, if I copy the query string at mongo shell or Campass, I just change 'date' to ISODate('date') it just work.
const filter = {
"user_id":ObjectId("61e403e4d3ec913651fcc51b"),
created_at: {
$gte: ISODate('2022-01-20T16:00:00.000Z'),
$lte: ISODate('2022-01-22T16:00:00.000Z')
}
}
what did you think? I don't have a clue...😵💫
This works for me:
const mongoose = require('mongoose');
const ReplSet = require('mongodb-memory-server').MongoMemoryReplSet;
async function main() {
// Create new instance
const replSet = new ReplSet({
instanceOpts: [
// Set the expiry job in MongoDB to run every second
{
port: 27017,
args: ["--setParameter", "ttlMonitorSleepSecs=1"]
},
],
dbName: 'mongoose_test',
replSet: {
name: "rs0",
count: 2,
storageEngine: "wiredTiger",
},
});
await replSet.start();
await replSet.waitUntilRunning();
const uri = replSet.getUri('mvce');
await mongoose.connect(uri);
const userSchema = mongoose.Schema(
{
email: String,
},
{ timestamps: { createdAt: 'created_at', updatedAt: 'updated_at' } }
);
const User = mongoose.model("User", userSchema);
const doc = await User.create({ email: "test@google.com" });
console.log(doc.created_at instanceof Date); // true
// empty result
console.log(await User.find({created_at: {
$gte: new Date(2022, 0, 21),
$lte: new Date(2022, 0, 23),
}}));
// should find one
console.log(await User.find({created_at: {
$gte: new Date(2022, 0, 21),
$lte: new Date(2022, 0, 25),
}}));
process.exit();
}
main();
Probably you dont use model to create a mongoose model or so...
@Uzlopak Thank you very much, I found the crux of the problem... It was my fault...
const filter = {
user_id: new Types.ObjectId(props.user_id),
status: props.status, // ---> **undefined** It is the root of the problem😂
created_at: {},
};
if (props.date) {
filter.created_at = {
$gte: dayjs(props.date).startOf('date'),
$lte: dayjs(props.date).endOf('date'),
};
}
// ---> final filter
filter = {
user_id: new ObjectId("61e403e4d3ec913651fcc51b"),
status: undefined, // oops
created_at: {....}
}
Why I didn't find it before?
logger.debug('findAll:', JSON.stringify(filter));
So, the JSON.stringify()
will ignore key of undefined...Thank you again, thank you for helping me solve the problem
problem
this is Schema:
now I would like to query date by created_ad, like below:
but result is [];
so I copy the query to MongoDB Campass & use ISODate(): It works!
but why? I follow the guide of mongoose doc: https://mongoosejs.com/docs/guide.html#timestamps
Versions
"@nestjs/mongoose": "^9.0.2" "mongoose": "^6.1.6" "nodejs": "14.17"