2017-05-15 5 views
0

Ich habe eine Abfrage in MongoDB, die Datensätze basierend auf bestimmten Kriterien ziehen soll. Ich denke, ich verstehe vielleicht nicht, wie die Aggregationspipeline funktioniert. Die Abfrage in Fragen zieht Datensätze zum größten Teil korrekt, aber es bringt einige Datensätze, die nicht den Kriterien entsprechen. Es scheint der Datumsteil der Abfrage zu sein, der dies verursacht, und ich denke, dass ich es falsch mache. Jede Hilfe wäre willkommen.MongoDB Aggregationsdatum Problem

Abfrage:

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", 
     } 
    } 
]; 

Diese zum größten Teil mit Ausnahme der dritten Zeile arbeitet { $match: { $or: [{ "Payments.ScheduledDate": { $lt: theLast, $gt: theFirst } }, { "Reports.ScheduledDate": { $lt: theLast, $gt: theFirst } }] } }, ich alle Dokumente wollen, wo Zahlungen (Embedded Array) einen geplanten Zeitpunkt der greater than $gt 2016.01.01 UND less than $lt 01/01/2017 ODER Berichte (eingebettetes Array) haben ein geplantes Datum von greater than $gt 01/01/2016 UND less than $lt 01/01/2017

Es zieht ein Dokument, wo es einen Bericht mit einem geplanten Datum 30/12/2017 hat was offensichtlich auf Teil trifft, wenn die Kriterien aber sein mögen Ignorieren der $ lt. Idealerweise sollte dieser Datensatz nicht zurückgegeben werden.

Eines der Dokumente es Rückkehr hat einen Bericht Sammlung wie folgt aus:

"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" 
    } 
] 

Einer der Berichte größer als 2016.01.01, aber es ist nicht weniger als 01/01/2017.I brauche die Abfrage nur zu ziehen, wo das Datum zwischen diesen beiden Daten entweder nicht oder landet.

Hier ist ein Bericht-Array, das ich zurückgeben würde, wenn ich verwenden würde. Wie Sie unten sehen können, gibt es einen Bericht vom 31.12.2016, der unseren Kriterien entsprechen sollte, aber nicht zurückkommt.

`"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

Fügen Sie ein Beispieldokument hinzu, das das Problem reproduziert. Das "$ match" in der Frage wird in "true" aufgelöst, wenn mindestens eine Zahlung oder ein Bericht der Bedingung entspricht. –

+0

Ich habe eine Sammlung hinzugefügt, die nicht gezogen werden soll. Das ist, dass das $ match nicht richtig funktioniert, das ein $ lt und $ gt zusammen sein sollte, aber es benutzt nur eins, das wie das $ gt aussieht. – Ohjay44

+0

Hat das Dokument irgendetwas im Payments-Array? Es ist eine 'or'-Bedingung, was bedeutet, wenn eines der Arrays ein passendes Element hat, wird es in true aufgelöst. –

Antwort

0

Die Antwort ist ganz einfach dank @Veeram. Ich musste $elemMatch verwenden und wenn ich das verwende, muss ich eingebettete Arrays als iterative Objekte in meiner Abfrage behandeln.

Abschlussarbeitscode:

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", 
    } 
} 
]; 

Sie befinden sich auf der dritten Zeile sehen, wo ich $elemMatch verwenden und das funktioniert.