Do you want to request a feature or report a bug?
Not sure if it's a bug or not and neither if it's related to mongoose or mongo
What is the current behavior?
I could find
elements greater
as a Date.now()
but if I do the same with aggregate
it doesn't find any elements
let query = {
something: : {$gte: Date.now()}
};
Collection.find(query).exec(function (err, results) {
console.log(results.length); // --> All good, x elements found
}
Collection.aggregate([{$match: query}], function (err, items) {
console.log(results.length); // --> 0 elements found
}
if I modify the query with new Date()
instead of Date.now()
, problem is solved
let query = {
something: : {$gte: new Date()}
};
Collection.aggregate([{$match: query}], function (err, items) {
console.log(results.length); // --> All good, x elements found
}
If the current behavior is a bug, please provide the steps to reproduce.
See above code
What is the expected behavior?
Would be cool to have the same behavior between find
and aggregate
regarding this comparison.
Please mention your node.js, mongoose and MongoDB version.
Node v9.4.0
mongoose v5.0.6
mongo v3.2.14
it looks like this is a difference in the way find and aggregate work in mongodb. I created a test collection with this populate script:
#!/usr/bin/env node
'use strict'
const mongoose = require('../lib/test_db')
const Schema = mongoose.Schema
const faker = require('faker')
const testSchema = new Schema({
what: String,
when: Date
})
const Test = mongoose.model('test', testSchema)
const docs = []
for (let i = 0; i < 100; i++) {
docs.push(new Test({
what: faker.company.bsAdjective(),
when: faker.date.past()
}))
docs.push(new Test({
what: faker.hacker.adjective(),
when: faker.date.future()
}))
}
Test.create(docs)
.then(
(res) => console.log(res),
(rej) => console.error(rej)
)
my find script:
#!/usr/bin/env node
'use strict'
const mongoose = require('../lib/test_db')
const Schema = mongoose.Schema
const testSchema = new Schema({
what: String,
when: Date
})
const Test = mongoose.model('test', testSchema)
const query = {
when: { $lte: Date.now() }
}
Test.find(query).exec((err, res) => {
if (err) { return console.error(err) }
console.log(`I found ${res.length} documents`)
})
it's output:
InspiredMacPro:Help lineus$ ./mongoose5/6170/find.js
I found 100 documents
^C
my aggregate script:
#!/usr/bin/env node
'use strict'
const mongoose = require('../lib/test_db')
const Schema = mongoose.Schema
const testSchema = new Schema({
what: String,
when: Date
})
const Test = mongoose.model('test', testSchema)
const query = {
when: { $lte: new Date(Date.now()) }
}
Test.aggregate([{ $match: query }], (err, res) => {
if (err) { return console.error(err) }
console.log(`I aggregated ${res.length} documents`)
})
it's output:
InspiredMacPro:Help lineus$ ./mongoose5/6170/aggregate.js
I aggregated 100 documents
^C
i couldn't get it to work until I found this old bug which alludes to using toDate ( I'm assuming from moments.js ) in the query. While testing in the mongo shell, I used mongodb's builtin Date object ( new Date() returns a date object instead of a string ) instead and it works.
If using the same query is important, or just preferable to you, find can accept the date object as well.
Mongoose does not cast aggregation pipeline stages because with $project
, $group
, etc. the type of a property may change during the aggregation. We've considered supporting casting if the first stage is $match
but that seems like too much magic. If you want to query by date using the aggregation framework, you're responsible for ensuring that you're passing in a valid date.
@lineus @vkarpov15 thx a lot for debugging this and for the explanation
well noted, aggregate need valid date aka use new Date()
instead of Date.now()
in case you want to compare with actual date in an aggregation. I'm all fine with than then.
again thx a lot for taking the time to look at this, really appreciated!
I'm going to re-open this so I can track putting this in the FAQ
Still not working with me. I turned on mongoose debug flag. and I am using
const responses = await responseModel.aggregate([
{
$match: {
myId: mongoose.Types.ObjectId('00000000000000000000000a'),
},
},
]);
and here is the result in console:
Mongoose: Responses.aggregate([ { '$match': { workflowId: 00000000000000000000000a } } ], {})
sorry for misunderstanding. It is working correctly however the logs are incorrect that's why I got confused.
Fixed in #6184
Most helpful comment
Fixed in #6184