2017-05-15 10 views
0

MongoDBには、特定の基準に基づいてレコードを取得するクエリがあります。私は、集約パイプラインがどのように機能するのか誤解していると思います。質問の質問は、ほとんどの場合、レコードを正しく引っ張っていますが、条件に一致しないレコードがいくつか取り込まれています。これを引き起こしているクエリの日付部分のように思われ、私はそれが間違っているかもしれないと思う。どんな助けもありがとう。MongoDB集計日発行

問合せ:

var theFirst = new Date("2016", "0", "1", "0", "0", "0", "0"); 
var theLast = new Date("2017", "0", "1", "0", "0", "0", "0"); 

var query = [ 
    { $match: { $and: [{ "ProjectName": { '$regex': '^((?!win).)*$', '$options': 'i' } }, { "ProjectName": { '$regex': '^((?!Champion Cooler recommended).)*$', '$options': 'i' } }] } }, 
    { $match: { $or: [{ "Payments": { $exists: true } }, { "Reports": { $exists: true } }] } }, 
    { $match: { $or: [{ "Payments.ScheduledDate": { $lt: theLast, $gt: theFirst } }, { "Reports.ScheduledDate": { $lt: theLast, $gt: theFirst } }] } }, { 
     $lookup: { 
      from: 'winorganizations', 
      localField: 'OrganizationId', 
      foreignField: '_id', 
      as: 'orgitem' 
     } 
    }, { 
     $project: { 
      _id: 0, 
      OrgName: '$Organization', 
      Address1: '$Org_Info.Address1', 
      Address2: '$Org_Info.Address2', 
      Address3: '$Org_Info.Address3', 
      OrgCity: '$Org_Info.City', 
      OrgState: '$Org_Info.State', 
      OrgZip: '$Org_Info.Zip', 
      TaxID: '$Org_Info.TaxId', 
      orgitem: '$orgitem', 
      OrgContactName: "", 
      OrgContactEmailAddress: "", 
      GrantContactName: { "$arrayElemAt": ["$Contacts.Name", 0] }, 
      GrantContactEmail: { "$arrayElemAt": ["$Contacts.Email", 0] }, 
      GrantNbr: "$WINNbr", 
      AmtApproved: "$Amount", 
      DateAccepted: "$DateAccepted", 
      ProjectName: "$ProjectName", 
      ProgramArea: "$ProgramArea", 
      Initiative: "$Initiative", 
      Strategy: "$Strategy", 
      ProgramOfficer: "$programOfficer", 
     } 
    } 
]; 

これは私が支払い(埋め込まれた配列)はgreater than $gt 2016年1月1日とless than $lt 01/01の予定日を持っているすべての文書をしたい三行目{ $match: { $or: [{ "Payments.ScheduledDate": { $lt: theLast, $gt: theFirst } }, { "Reports.ScheduledDate": { $lt: theLast, $gt: theFirst } }] } },を除くほとんどの部分のために働きます/ 2017 ORレポート(エンベデッドアレイ)の予定日はgreater than $gt 01/01/2016 AND less than $lt 01/01/2017

2011年12月12日の予定日のレポートがある文書を引き出していますそれは明らかに基準によっては部分的に会うが、 $ ltを無視します。理想的には、このレコードは返されません。

それはリターンでの文書の一つは、このようなレポートのコレクションを持っています

"Reports" : [ 
    { 
     "ProgramOfficer" : "eah", 
     "ProgramOfficerId" : "eah", 
     "ApprovedDate" : ISODate("2013-12-04T06:00:00.000Z"), 
     "Note" : "received emailed image", 
     "ReportTypeId" : "12", 
     "ReportType" : "ACK", 
     "ScheduledDate" : ISODate("2013-12-10T06:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "MH", 
     "ProgramOfficerId" : "MH", 
     "ApprovedDate" : ISODate("2014-11-03T06:00:00.000Z"), 
     "Note" : "Reports recevied and sent to MH 10.31.2014", 
     "ReportTypeId" : "6", 
     "ReportType" : "F,N.", 
     "ScheduledDate" : ISODate("2014-11-01T05:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "n/a", 
     "ProgramOfficerId" : "n/a", 
     "ApprovedDate" : null, 
     "Note" : "12.22.16 MH approves Second no-cost extension. First no-cost extension was due 2/1/2017. Original due date was 12/1/15. Umut Ozek asked MH for a 1 year extension for the term of the contract and a 2 year extension on the final report. See email in Report folder.", 
     "ReportTypeId" : "30", 
     "ReportType" : "FINAL", 
     "ScheduledDate" : ISODate("2017-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    }, 
    { 
     "ProgramOfficer" : "TG", 
     "ProgramOfficerId" : "TG", 
     "ApprovedDate" : ISODate("2014-06-06T05:00:00.000Z"), 
     "Note" : "need original", 
     "ReportTypeId" : "12", 
     "ReportType" : "ACK", 
     "ScheduledDate" : ISODate("2014-01-10T06:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    } 
] 

レポートの一つは、2016年1月1日より大きいですが、それは01/01/2017.I未満ではありませんそれらの2つの日付の間に日付がどこにあるのかを判断する必要があります。

ここでは、$elemMatchを使用すると返される予定のレポート配列を示します。下に向かって見ることができるように、2015年12月31日のレポートがありますが、それは私たちの基準に一致するはずですが、それは返されません。

`"Reports" : [ 
    { 
     "ProgramOfficer" : "DKO", 
     "ProgramOfficerId" : "DKO", 
     "ApprovedDate" : ISODate("2007-03-19T05:00:00.000Z"), 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2007-03-31T05:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : ISODate("2008-03-16T05:00:00.000Z"), 
     "Note" : "Gave to Nac", 
     "ReportTypeId" : "9", 
     "ReportType" : "N.", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "NGW", 
     "ProgramOfficerId" : "NGW", 
     "ApprovedDate" : ISODate("2009-01-16T06:00:00.000Z"), 
     "Note" : "Financial Activity Rpt", 
     "ReportTypeId" : "7", 
     "ReportType" : "F.", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "NGW", 
     "ProgramOfficerId" : "NGW", 
     "ApprovedDate" : ISODate("2009-03-31T05:00:00.000Z"), 
     "Note" : "2008 Annual Rpt", 
     "ReportTypeId" : "17", 
     "ReportType" : "ANNUAL", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "NGW", 
     "ProgramOfficerId" : "NGW", 
     "ApprovedDate" : ISODate("2010-01-08T06:00:00.000Z"), 
     "Note" : "", 
     "ReportTypeId" : "19", 
     "ReportType" : "UPDATE", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "n/a", 
     "ProgramOfficerId" : "n/a", 
     "ApprovedDate" : ISODate("2011-01-07T06:00:00.000Z"), 
     "Note" : "Gave to Nac", 
     "ReportTypeId" : "19", 
     "ReportType" : "UPDATE", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "NGW", 
     "ProgramOfficerId" : "NGW", 
     "ApprovedDate" : ISODate("2012-01-09T06:00:00.000Z"), 
     "Note" : "Investments down.", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "sn", 
     "ProgramOfficerId" : "sn", 
     "ApprovedDate" : ISODate("2014-01-02T06:00:00.000Z"), 
     "Note" : "n/a", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2013-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "NGW", 
     "ProgramOfficerId" : "NGW", 
     "ApprovedDate" : ISODate("2012-05-05T05:00:00.000Z"), 
     "Note" : "Annual report, overall foundation investment down from 2011.", 
     "ReportTypeId" : "17", 
     "ReportType" : "ANNUAL", 
     "ScheduledDate" : null, 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "n/a", 
     "ProgramOfficerId" : "n/a", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2014-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "AB", 
     "ProgramOfficerId" : "AB", 
     "ApprovedDate" : ISODate("2016-05-06T05:00:00.000Z"), 
     "Note" : "Received via email 5/6/16; Reviewed with SN", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2015-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Complete", 
     "ReportStatusId" : "6eebae88-fca3-4b21-ad80-283eeb564f3f" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2016-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2017-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2018-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2019-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    }, 
    { 
     "ProgramOfficer" : "", 
     "ProgramOfficerId" : "", 
     "ApprovedDate" : null, 
     "Note" : "", 
     "ReportTypeId" : "26", 
     "ReportType" : "ENDOWMENT", 
     "ScheduledDate" : ISODate("2020-12-31T06:00:00.000Z"), 
     "ReportStatus" : "Pending", 
     "ReportStatusId" : "" 
    } 
],` 
+0

問題を再現するサンプルドキュメントを追加してください。質問の '$ match'は、少なくとも1つのPaymentまたはReportが条件に一致する場合にtrueになります。 –

+0

私は引っ張ってはならない引っ張っているコレクションを追加しました。これは、$一致が正しく機能していないため、$ ltと$ gtを一緒にする必要がありますが、$ gtのようなものを使用するだけです。 – Ohjay44

+0

文書にPayments配列の内容がありますか?それは 'or'条件です。どちらかの配列に一致する項目がある場合、trueに解決されます。 –

答えて

0

答えは@Veeramのおかげで非常に簡単です。私は$elemMatchを使用する必要があり、それを使用するときには、クエリで反復オブジェクトとして埋め込み配列を処理する必要があります。

最終作業コード:

var query = [ 
{ $match: { $and: [{ "ProjectName": { '$regex': '^((?!win).)*$', '$options': 'i' } }, { "ProjectName": { '$regex': '^((?!Champion Cooler recommended).)*$', '$options': 'i' } }] } }, 
{ $match: { $or: [{ "Payments": { $exists: true } }, { "Reports": { $exists: true } }] } }, 
{ $match: { $or: [{ "Payments": {$elemMatch: {"ScheduledDate": { $lt: theLast, $gte: theFirst } } } }, { "Reports": {$elemMatch: {"ScheduledDate": { $lt: theLast, $gte: theFirst } } } }] } }, { 
    $lookup: { 
     from: 'winorganizations', 
     localField: 'OrganizationId', 
     foreignField: '_id', 
     as: 'orgitem' 
    } 
}, { 
    $project: { 
     _id: 0, 
     OrgName: '$Organization', 
     Address1: '$Org_Info.Address1', 
     Address2: '$Org_Info.Address2', 
     Address3: '$Org_Info.Address3', 
     OrgCity: '$Org_Info.City', 
     OrgState: '$Org_Info.State', 
     OrgZip: '$Org_Info.Zip', 
     TaxID: '$Org_Info.TaxId', 
     orgitem: '$orgitem', 
     OrgContactName: "", 
     OrgContactEmailAddress: "", 
     GrantContactName: { "$arrayElemAt": ["$Contacts.Name", 0] }, 
     GrantContactEmail: { "$arrayElemAt": ["$Contacts.Email", 0] }, 
     GrantNbr: "$WINNbr", 
     AmtApproved: "$Amount", 
     DateAccepted: "$DateAccepted", 
     ProjectName: "$ProjectName", 
     ProgramArea: "$ProgramArea", 
     Initiative: "$Initiative", 
     Strategy: "$Strategy", 
     ProgramOfficer: "$programOfficer", 
    } 
} 
]; 

あなたは、私が$elemMatchを使用し、その作品3行目に表示されます。