【问题标题】:MongoDB filter $lookup documents with date rangeMongoDB 过滤 $lookup 具有日期范围的文档
【发布时间】:2019-02-19 03:06:02
【问题描述】:

我有一个查询,输出如下。

return ChallengeModel.aggregate([
    { $match: { is_processed: false,} },
    { $lookup: {
        from: 'scoreboards',
        let: { 'challengeId': '$_id' },
        pipeline: [{ $match: { $expr: { $eq: [ '$challenge_id', '$$challengeId' ]}} }],
        as: 'scoreboards'
    } }
]);

输出:

{
  "_id": "5b9679db0a3d61258aa3ffc3",
  "voucher_paid_by": "issuer",
  "start_date": "2018-09-03T00:00:00.000Z",
  "end_date": "2018-09-09T23:59:00.000Z",
  "accept_by_date": "2018-09-03T12:00:00.000Z",
  "scoreboards": [
    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-01T00:00:00.000Z",
      "value": 2
    },
    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-02T00:00:00.000Z",
      "value": 6
    },
    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-03T00:00:00.000Z",
      "value": 5
    },
    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-04T00:00:00.000Z",
      "value": 9
    },
    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-05T00:00:00.000Z",
      "value": 7
    },

    {
      "_id": "5b9757c68a6f1615d8e704d3",
      "user_id": "5b9667200a3d61258aa3ff9f",
      "date": "2018-09-06T00:00:00.000Z",
      "value": 1
    }
  ]
}

我从输出中去掉了challenge_id,所以输出只是一个例子。

现在我想执行相同的查询,我只想要在 start_date 和 end_date 范围内的记分牌数据。

所以我做了这样的事情。

return ChallengeModel.aggregate([
    { $match: { is_processed: false,} },
    { $lookup: {
        from: 'scoreboards',
        let: { 'challengeId': '$_id', 'startDate': '$start_date', 'endDate': '$end_date' },
        pipeline: [{ $match: { 
            date: { $gte: '$$startDate', $lt: '$$endDate' },
            $expr: { $eq: [ '$challenge_id', '$$challengeId' ]}} 
        }],
        as: 'scoreboards'
    } }
]);

但它返回记分牌的空数组。我做得对吗?

【问题讨论】:

    标签: node.js mongodb aggregation-framework


    【解决方案1】:

    您需要使用$expr 与其他字段以及$match 文档的相同字段。

    ChallengeModel.aggregate([
      { "$match": { "is_processed": false,} },
      { "$lookup": {
        "from": "scoreboards",
        "let": { "challengeId": "$_id", "startDate": "$start_date", "endDate": "$end_date" },
        "pipeline": [
          { "$match": {
            "$expr": {
              "$and": [
                { "$eq": [ "$challenge_id", "$$challengeId" ] },
                { "$gte": [ "$date", "$$startDate" ] },
                { "$lt": [ "$date", "$$endDate" ] }
              ]
            }
          }}
        ],
        "as": "scoreboards"
      }}
    ])
    

    【讨论】:

    • 谢谢安东尼。你一直都在救我。 :)
    • 我还有一件事要问。我可以只比较日期和日期字段吗?我想更新 '2018-09-07' 的记录,但 mongoDB 总是将时间与日期进行比较,如下所示... {"date": "2018-09-07T18:30:00.000Z"} {"date": "2018 -09-07T00:00:00.000Z"} 只比较日期而不比较时间的方法是什么?
    • 您必须为此使用dateFromParts 聚合
    • 我现在需要深入研究一下。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    相关资源
    最近更新 更多