Как отфильтровать документы в $ match за последние 36 месяцев в агрегации MongoDB - PullRequest
0 голосов
/ 10 января 2020

Я хочу получить документы только в том случае, если это поле c указанного "EffectiveDate" превышает 36 месяцев go. Я пробовал:

"$match" : 
{"member.MemberEnrollmentSpans.MemberEnrollmentSpan.EffectiveDate": {$gte: 
ObjectID.createFromTime(Date.now() - 36*31*24*60*60)}}

Но это не похоже на выражение 'ObjectID.createFromTime', оно говорит, что моя ошибка в позиции 'O', "Unexpected Character 'O'"

Оператор $match не распознает это или мой синтаксис неверен?

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
}

);

Ответы [ 2 ]

2 голосов
/ 10 января 2020

Попробуйте:

В вашем коде:

let date = new Date();
(date.setMonth(date.getMonth() - 36));
let dateInput = date.toLocaleDateString(); // 1/10/2017

Запрос 1:

db.yourCollectionName.aggregate([{ $match: { $expr: { $lt: [{ $toDate: dateInput }, "$date"] } } }])

Сбор данных:

/* 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")
}

Результат:

/* 1 */
{
    "_id" : ObjectId("5e17a6c0627ef7823644a2d6"),
    "date" : ISODate("2019-12-01T00:00:00.000Z")
}

(или) отсюда getOlderRecordsByMins , вы можете сделать это, и то и другое даст вам те же результаты, но получить 36 месяцев на это число 94608103680 немного сложно, оба эти запроса просты и достаточно быстры, с меньшим количеством используемых операторов - но если вы думаете, что получить 94608103680 через код проще, чем этот go вперед с этим:

Запрос 2:

db.yourCollectionName.aggregate([
    { $match: { date: { $gt: new Date(ISODate().getTime() - 94608103680) } } }])
1 голос
/ 10 января 2020

Я использую подход, согласно которому 36 месяцев - это 3 года. Таким образом, совокупные запросы могут быть одним из следующих:

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() }  
                 } }
              ]
          }
      } 
  }
] )

Со следующими входными документами:

{ "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") }

они будут возвращены:

{ "EffectiveDate" : ISODate("2020-01-05T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2017-08-10T03:42:26.751Z") }
{ "EffectiveDate" : ISODate("2018-05-30T03:42:26.751Z") }
...