问题
I want to only obtain documents where this specific field "EffectiveDate" is greater than 36 months ago. I have tried:
"$match" :
{"member.MemberEnrollmentSpans.MemberEnrollmentSpan.EffectiveDate": {$gte:
ObjectID.createFromTime(Date.now() - 36*31*24*60*60)}}
But It doesn't seem to like the 'ObjectID.createFromTime
' statement, it say my error is at the 'O' position, "Unexpected Character 'O'"
Does $match
operator not recognize this or is my syntax wrong ?
var date = new Date();
(date.setMonth(date.getMonth() - 36));
var dateInput = date.toLocaleDateString();
db.getCollection("Members").aggregate(
[
{
"$match" : {
"member.MemberInfo.BusinessUnitCode" : "20"
}
},
{
"$match": { $expr: { $lt: [{ $toDate: dateInput },
"$member.MemberEnrollmentSpans.MemberEnrollmentSpan.EndDate"] } }
},
{
"$unwind" : {
"path" :
"$member.MemberEnrollmentSpans.MemberEnrollmentSpan",
"preserveNullAndEmptyArrays" : false
}
},
{
"$project" : {
"EffDate" : "$member.MemberEnrollmentSpans.MemberEnrollmentSpan.EffectiveDate",
"PlanProduct" : "$member.MemberEnrollmentSpans.MemberEnrollmentSpan.PlanProduct",
"PlanProductCode" : "$member.MemberEnrollmentSpans.MemberEnrollmentSpan.PlanProductCode",
"BenefitPackage" : "$member.MemberEnrollmentSpans.MemberEnrollmentSpan.BenefitPackage",
"EndDate" : "$member.MemberEnrollmentSpans.MemberEnrollmentSpan.EndDate"
}
},
{
"$group" : {
"_id" : "$_id",
"items" : {
"$addToSet" : {
"EffDate" : "$EffDate",
"PlanProductCode" : "$PlanProductCode",
"PlanProduct" : "$PlanProduct",
"BenefitPackage" : "$BenefitPackage",
"EndDate" : "$EndDate"
}
}
}
}
],
{
"allowDiskUse" : true
}
);
回答1:
Try this :
In your code :
let date = new Date();
(date.setMonth(date.getMonth() - 36));
let dateInput = date.toLocaleDateString(); // 1/10/2017
Query 1 :
db.yourCollectionName.aggregate([{ $match: { $expr: { $lt: [{ $toDate: dateInput }, "$date"] } } }])
Collection Data :
/* 1 */
{
"_id" : ObjectId("5e17a6a5627ef7823644a088"),
"date" : ISODate("2015-08-01T00:00:00.000Z")
}
/* 2 */
{
"_id" : ObjectId("5e17a6ac627ef7823644a13f"),
"date" : ISODate("2016-08-01T00:00:00.000Z")
}
/* 3 */
{
"_id" : ObjectId("5e17a6c0627ef7823644a2d6"),
"date" : ISODate("2019-12-01T00:00:00.000Z")
}
Result :
/* 1 */
{
"_id" : ObjectId("5e17a6c0627ef7823644a2d6"),
"date" : ISODate("2019-12-01T00:00:00.000Z")
}
(Or) as from here getOlderRecordsByMins, you can do this, both would get you same results but getting 36
months to this number 94608103680
is a bit hard, both of these queries are simple & fast enough with less operators being used - but if you think getting 94608103680
through code is easier then this go ahead with this :
Query 2 :
db.yourCollectionName.aggregate([
{ $match: { date: { $gt: new Date(ISODate().getTime() - 94608103680) } } }])
回答2:
I take the approach that 36 months is 3 years. So, the aggregate queries can be one of these:
db.test.aggregate( [
{
$match: {
EffectiveDate: { $gt: new Date(new Date().setFullYear(new Date().getFullYear() - 3 ) ) }
}
}
] )
db.test.aggregate( [
{
$match: {
$expr: {
$gt: [
"$EffectiveDate",
{ $dateFromParts: {
year : { $subtract: [ { $year: ISODate() }, 3 ] } ,
month : { $month: ISODate() },
day: { $dayOfMonth: ISODate() }
} }
]
}
}
}
] )
With the following input documents:
{ "EffectiveDate" : ISODate("2016-12-10T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2020-01-05T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2017-08-10T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2017-01-09T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2018-05-30T03:42:26.751Z") }
these will be returned:
{ "EffectiveDate" : ISODate("2020-01-05T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2017-08-10T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2018-05-30T03:42:26.751Z") }
来源:https://stackoverflow.com/questions/59672412/how-to-filter-documents-in-match-by-the-last-36-months-in-mongodb-aggregation