You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何设计MongoDB结构,使日期查询后返回指定电影场次信息?

解决MongoDB影院场次查询问题

嘿,我来帮你搞定这个影院场次查询的需求~首先得提个关键点:你给的现有文档结构里没有存储场次时间的字段,这可是按时间筛选的核心信息呀!要实现你要的查询,咱们得先把文档结构补全,把影片名称和对应的场次时间都存进去。

完善后的文档结构示例

先给你一个符合查询需求的文档结构参考:

{
  "_id" : ObjectId("5abb086677d96df7015c56c6"),
  "theater" : "Madou",
  "movies" : [
    {
      "movieName": "Pacific Rim Uprising",
      "moviePhoto": [
        "https://movies.yahoo.com.tw/x/r/w420/i/o/production/movies/March2018/GD9otOLc6d3eprWHC1Ve-2757x4000.jpg",
        "https://movies.yahoo.com.tw/x/r/w420/i/o/production/movies/March2018/MueV..."
      ],
      "showtimes": [
        {"time": ISODate("2018-03-27 20:00:00.000Z")},
        {"time": ISODate("2018-03-27 21:00:00.000Z")},
        {"time": ISODate("2018-03-27 21:40:00.000Z")}
      ]
    },
    {
      "movieName": "Tomb Raider",
      "moviePhoto": [
        "https://example.com/tomb-raider-photo1.jpg",
        "https://example.com/tomb-raider-photo2.jpg"
      ],
      "showtimes": [
        {"time": ISODate("2018-03-27 19:30:00.000Z")},
        {"time": ISODate("2018-03-27 22:00:00.000Z")}
      ]
    }
  ]
}

这里把原来的单个movie字段改成了movies数组,每个元素包含影片名、海报和场次时间数组,这样就能精准筛选了。

实现目标查询的两种方案

方案一:用$elemMatch快速筛选(适合简单场景)

如果只是想快速拿到匹配的影片和对应场次,find结合$elemMatch就能搞定,但要注意它的局限:同一份文档里如果有多个匹配的影片,只会返回第一个匹配的对象。

db.theaters.find(
  {
    "movies.showtimes.time": { $gte: ISODate("2018-03-27 19:00:00.000Z") },
    "movies.movieName": { $in: ["Pacific Rim Uprising", "Tomb Raider"] }
  },
  {
    "movies": {
      $elemMatch: {
        "movieName": { $in: ["Pacific Rim Uprising", "Tomb Raider"] },
        "showtimes.time": { $gte: ISODate("2018-03-27 19:00:00.000Z") }
      }
    },
    "theater": 1
  }
)

方案二:聚合管道(灵活精准,强烈推荐)

要是想完整拿到所有符合条件的影片和场次,聚合管道是最优解,它能一步步过滤、拆分、重组数据,完全满足你的需求:

db.theaters.aggregate([
  // 第一步:先把包含目标影片且有符合时间场次的影院文档捞出来
  {
    $match: {
      "movies.movieName": { $in: ["Pacific Rim Uprising", "Tomb Raider"] },
      "movies.showtimes.time": { $gte: ISODate("2018-03-27 19:00:00.000Z") }
    }
  },
  // 第二步:把movies数组拆成单个文档,方便后续筛选
  { $unwind: "$movies" },
  // 第三步:筛选出咱们要的两部影片
  {
    $match: {
      "movies.movieName": { $in: ["Pacific Rim Uprising", "Tomb Raider"] }
    }
  },
  // 第四步:把场次数组也拆成单个文档
  { $unwind: "$movies.showtimes" },
  // 第五步:过滤出时间>=指定时间的场次
  {
    $match: {
      "movies.showtimes.time": { $gte: ISODate("2018-03-27 19:00:00.000Z") }
    }
  },
  // 第六步:按影片名称重新分组,把场次整理成数组
  {
    $group: {
      _id: "$movies.movieName",
      theater: { $first: "$theater" },
      moviePhoto: { $first: "$movies.moviePhoto" },
      showtimes: { $push: "$movies.showtimes.time" }
    }
  },
  // 可选步骤:调整输出格式,把_id换成更直观的movieName
  {
    $project: {
      _id: 0,
      movieName: "$_id",
      theater: 1,
      moviePhoto: 1,
      showtimes: 1
    }
  }
])

执行这个聚合管道后,你就能得到:

  • Pacific Rim Uprising的21:00、21:40场次
  • Tomb Raider的19:30场次

完全和你要的结果一致~

内容的提问来源于stack exchange,提问作者Morton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:28:32