检索 MongoDB 中特定月份和年份的 JSON 文档

Emi*_*uin 1 json mongodb

我正在尝试从 MongoDB 实例中的集合中检索一些文档。这是整个集合:

[
  {
    _id: ObjectId("65708c6237b62067296a398f"),
    date: ISODate("2020-09-15T04:07:05.000Z"),
    description: 'playstation',
    category: 'miscellaneous',
    cost: 499,
    users: [ { username: 'Giacomo', amount: 499 } ]
  },
  {
    _id: ObjectId("6570950cecb7eb1b4b868409"),
    date: ISODate("2020-09-15T04:07:05.000Z"),
    description: 'tennis court',
    category: 'sport',
    cost: 100,
    users: [
      { username: 'prova', amount: 50 },
      { username: 'Giacomo', amount: 50 }
    ]
  },
  {
    _id: ObjectId("6570953aecb7eb1b4b86840a"),
    date: ISODate("2023-02-09T03:12:15.012Z"),
    description: 'netflix subscription',
    category: 'entertainment',
    cost: 100,
    users: [ { username: 'prova', amount: 10 } ]
  }
]
Run Code Online (Sandbox Code Playgroud)

目前,我可以date使用以下查询检索具有特定年份的文档作为 值的一部分:

  db
    .collection("expenses")
    .find({
      "users.username": "desired_username",
      $expr: { $eq: [{ $year: "$date" }, 2020] },
    })
Run Code Online (Sandbox Code Playgroud)

下一步,我想检索不仅具有特定年份而且具有特定月份的文档(例如 2020 年 9 月应该返回前两个文档)。我不知道如何在查询中使用两个不同的表达式。

谁能帮我解决这个问题吗?

预先感谢您的耐心等待。

cmg*_*ess 6

用最简单的话来说,你可以有类似的东西

db.collection("expenses").find({
  "users.username": "desired_username",
  $expr: {
    $and: [
      { $eq: [{ $year: "$date" }, 2020] },
      { $eq: [{ $month: "$date" }, 9] }
    ]
  }
})
Run Code Online (Sandbox Code Playgroud)

操场

或者如果你想要更多奇特的东西,你可以使用类似日期的字符串格式(需要 mongo 7来使用%B和获取月份名称)

db.collection("expenses").find({
  "users.username": "desired_username",
  $expr: {
      { $eq: [{ $dateToString: { format: "%B, %Y", date: "$date" } }, "september, 2020"] }  
  }
})
Run Code Online (Sandbox Code Playgroud)

这在 mongoplayground 中不起作用,因为它在较低的 mongo 版本上运行

或者可能在旧版本上运行的东西,例如

db.collection("expenses").find({
  "users.username": "Giacomo",
  $expr: {
    $and: [
      { $eq: [{ $year: "$date" }, 2020] },
      {
        $eq: [
          {
            $arrayElemAt: [
              ["", "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"],
              { $month: "$date" }
            ]
          },
          "september"
        ]
      }
    ]
  }
})
Run Code Online (Sandbox Code Playgroud)

操场

好吧,最后一个只是为了好玩,但我想这太多了,使得查询有时难以理解(这正是第二种方法中显示的较长版本)

db.collection("expenses").find({
  "users.username": "Giacomo",
  $expr: {
    $and: [
      { $eq: [{ $year: "$date" }, 2020] },
      {
        $eq: [
          {
            $arrayElemAt: [
              ["", "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"],
              { $month: "$date" }
            ]
          },
          "september"
        ]
      }
    ]
  }
})
Run Code Online (Sandbox Code Playgroud)

操场

  • @jQueeny 是的,它看起来很新(至少是月份名称)。我最近也发现了 (2认同)
  • 实际上,如果我们只使用 `%m` 来格式化月份,我们不需要 MongoDB v7.0+。MongoDB v3.0+ 应该没问题 (2认同)