【问题标题】:Or statement returns the first result only (should be 2)Or 语句只返回第一个结果(应该是 2)
【发布时间】:2021-06-09 20:30:31
【问题描述】:

我有一个 OR 语句,其中预期结果应返回 2 个文档,但返回结果仅为 1 个文档。我有一份汽车文档列表:

[
  {
    "_id": ObjectId("60a2c0621e5f043b735e36ef"),
    "car_id": 78,
    "terminal": "JFK",
    "timestamp": ISODate("2020-01-01T17:00:00.000Z"),
    
  },
  {
    "_id": ObjectId("60a2c0621e5f043b735e36f0"),
    "car_id": 78,
    "terminal": "LAX",
    "timestamp": ISODate("2020-02-08T17:00:00.000Z"),
    
  },
  {
    "_id": ObjectId("60a2c0621e5f043b735e36f1"),
    "car_id": 78,
    "terminal": "ORD",
    "timestamp": ISODate("2020-03-01T17:00:00.000Z"),
    
  },
]

我的查询要求 2 个实例具有相同的 CAR ID 但具有不同的时间戳:

db.collection.aggregate([
  {
    "$match": {
      "$or": [
        {
          "car_id": 78,
          "timestamp": {
            "$lte": ISODate("2020-02-15T05:00:11.000Z")
          }
        },
        {
          "car_id": 78,
          "timestamp": {
            "$lte": ISODate("2020-03-02T11:07:27.000Z")
          }
        }
      ]
    }
  },
  {
    "$sort": {
      "timestamp": 1
    }
  },
  {
    "$group": {
      "_id": "$car_id",
      "last": {
        "$last": "$$ROOT"
      }
    }
  }
])

所以我希望得到 2 个结果(对于每个请求)。

预期结果:

[
  {
    "_id": 78,
    "last": {
      "_id": ObjectId("60a2c0621e5f043b735e36f1"),
      "car_id": 78,
      "terminal": "ORD",
      "timestamp": ISODate("2020-03-01T17:00:00Z")
    }
  },

  {
    "_id": 78,
    "last": {
      "_id": ObjectId("60a2c0621e5f043b735e36f0"),
      "car_id": 78,
      "terminal": "LAX",
      "timestamp": ISODate("2020-02-08T17:00:00Z")
    }
  }
]

但我只得到第一个结果。我怎样才能得到想要的 2 个结果?

mongoplayground

【问题讨论】:

  • 亲爱的 ProcolHarum,建议问题本身包含所有必要的信息。虽然 mongoplayground 是一项了不起的服务,并且提供了很多帮助,但您并不明显地也在对结果进行分组。
  • @AlexBlex 好的。我看到你添加了它。谢谢

标签: mongodb aggregate


【解决方案1】:

因为所有返回的文档都具有相同的car_id,并且您在$group 阶段使用car_id,所以它们将被分组为一个结果。要获得预期结果,您可以添加一个取决于文档时间戳的字段,然后使用 $group 中的字段:

db.collection.aggregate([
  {
    "$match": {
      "$or": [
        {
          "car_id": 78,
          "timestamp": {
            "$lte": ISODate("2020-02-15T05:00:11.000Z")
          }
        },
        {
          "car_id": 78,
          "timestamp": {
            "$lte": ISODate("2020-03-02T11:07:27.000Z")
          }
        }
      ]
    }
  },
  {
    "$sort": {
      "timestamp": 1
    }
  },
  {
    $addFields: {
      group: {
        $cond: {
          if: {
            $lte: [
              "$timestamp",
              ISODate("2020-02-15T05:00:11.000Z")
            ]
          },
          then: 1,
          else: 2
        }
      }
    }
  },
  {
    "$group": {
      "_id": "$group",
      "last": {
        "$last": "$$ROOT"
      }
    }
  }
])

Mongoplayground

注意:如果结果中有多个car_id,您可以将$group更改为:

{
  "$group": {
    "_id": {
      car_id: "$car_id",
      group: "$group",
    },
    "last": {
      "$last": "$$ROOT"
    }
  }
}

Mongoplayground

【讨论】:

    猜你喜欢
    • 2014-04-17
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    相关资源
    最近更新 更多