0

我环顾四周,找不到解决此问题的确切方法。我浏览了 Mongoose 文档并试图找到一种方法。我是 MongoDB 的新手,在学习了很多教程之后,我想致力于制作自己的 API。

目的:

GET 请求http://localhost:3000/seasons/19/1 并返回系列详细信息19和所选剧集1

就像是:

{
        "_id": "5b893aff76c12c166c4e75ae",
        "season_number": 19,
        "name": "Season 19",
        "number_of_episodes": 24,
        "episode": [
            {
                "_id": "5b895e56089a9a152c16af1f",
                "episode_number": 1,
                "name": "19.01",
                "length": "1:23:33",
                "author": "Aaron Wright",
                "release": "2018-01-13T00:00:00.000Z",
                "description": "We kick off our 2018 season with the worst of CES and the future of smart toilets before Aaron unravels the controversial “Dear David” saga that has sparked controversy. We then look at state sponsored mind control programs and the hypnotic experiments performed on unwitting Princeton students in the 1960s."
            },

}

问题:

我似乎无法弄清楚如何仅使用一个选定的剧集返回上述对象。由于所有数据都在episodes但如果我手动使用episodes[0]等我可以返回它。

这是回购文件,所以不要让这篇文章太长: https ://github.com/DannnB/mysterious-universe-api/blob/master/api/controllers/seasons.js

  • 线路63
  • 姓名seasons_get_episode_number

谢谢你的帮助!

该数据库- 托管在 MongoDB Atlas 上 - 免费层,因此无法使用$where,也不想将$where其用作繁重的命令。

 "data": [
    {
        "_id": "5b893aff76c12c166c4e75ae",
        "season_number": 19,
        "name": "Season 19",
        "number_of_episodes": 24,
        "episodes": [
            {
                "_id": "5b895e56089a9a152c16af1f",
                "episode_number": 1,
                "name": "19.01",
                "length": "1:23:33",
                "author": "Aaron Wright",
                "release": "2018-01-13T00:00:00.000Z",
                "description": "We kick off our 2018 season with the worst of CES and the future of smart toilets before Aaron unravels the controversial “Dear David” saga that has sparked controversy. We then look at state sponsored mind control programs and the hypnotic experiments performed on unwitting Princeton students in the 1960s."
            },
            {
                "_id": "5b895fee089a9a152c16af20",
                "episode_number": 2,
                "name": "19.02",
                "length": "1:22:11",
                "author": "Benjamin Grundy",
                "release": "2018-01-20T00:00:00.000Z",
                "description": "This week we unravel the cosmic serpent to find the origins of life and the link between DNA and Ayahuasca visions. Could the building blocks of all life also be a conscious force that is capable of direct communication with our altered states of mind?"
            }
        ]
    },
    {
        "_id": "5b893b2276c12c166c4e75b0",
        "season_number": 20,
        "name": "Season 20",
        "number_of_episodes": 9
    }, *and so on...*
]
4

3 回答 3

1

您可以使用Aggregation上可用的$filter运算符。以下是符合您要求的查询:

db.seasons.aggregate([
  { "$match": { "season_number": 19 } },
  { "$project": {
       "season_number": 1,
       "name": 1,
       "number_of_episodes": 1,
       "episodes": {
          "$filter": {
             "input":  "$episodes",
             "as": "episode",
             "cond": { "$eq": [ "$$episode.episode_number", 1 ] }
          }
       }
    } 
  }])

$filter从 3.2 版本开始可用

于 2018-09-03T15:04:11.997 回答
0

编辑:通过使用 $filter

最初在这里找到解决方案

db.dumb.aggregate(
    {
        $match:{a:'ok', eps:{$elemMatch:{id:1}}}
    },
    {
        $project:{
            a:1, 
            eps:{
                $filter:{
                    input:'$eps', 
                    as:'ep', 
                    cond:{$eq:['$$ep.id',1]}
                }
            }
        }
    }
)

输出

{ "_id" : ObjectId("5b8e3eb8e5ab5ef9a9b9b673"), "a" : "ok", "eps" : [ { "id" : 1, "comment" : "ok" } ] }
{ "_id" : ObjectId("5b8e3ec3e5ab5ef9a9b9b676"), "a" : "ok", "eps" : [ { "id" : 1, "comment" : "ok too" } ] }

也许使用放松?

构建数据集

> db.dumb.insert({a:'ok', eps:[{id:1, comment('ok')}]})
WriteResult({ "nInserted" : 1 })
> db.dumb.insert({a:'ko', eps:[{id:1, comment:'ok'}]})
WriteResult({ "nInserted" : 1 })
> db.dumb.insert({a:'ok', eps:[{id:2, comment:'ko'}]})
WriteResult({ "nInserted" : 1 })
> db.dumb.insert({a:'ok', eps:[{id:2, comment:'ko'}, {id:1, comment:'ok too'}]})
WriteResult({ "nInserted" : 1 })

匹配系列(此处命名为“ok”)

> db.dumb.find({a:'ok', eps:{$elemMatch:{id:1}}})
{ "_id" : ObjectId("5b8d447b21edbcdd7f3b3d24"), "a" : "ok", "eps" : [ { "id" : 1, "comment" : "ok" } ] }
{ "_id" : ObjectId("5b8d449d21edbcdd7f3b3d27"), "a" : "ok", "eps" : [ { "id" : 2, "comment" : "ko" }, { "id" : 1, "comment" : "ok too" } ] }

使用展开匹配名为“ok”的系列 id 1 的电影,数组的每个项目都是“展开”的。注意“重复的 objectIds”(您正在跟踪您的展开文档)

> db.dumb.aggregate({$match:{a:'ok'}},{$unwind:'$eps'})
{ "_id" : ObjectId("5b8d447b21edbcdd7f3b3d24"), "a" : "ok", "eps" : { "id" : 1, "comment" : "ok" } }
{ "_id" : ObjectId("5b8d449121edbcdd7f3b3d26"), "a" : "ok", "eps" : { "id" : 2, "comment" : "ko" } }
{ "_id" : ObjectId("5b8d449d21edbcdd7f3b3d27"), "a" : "ok", "eps" : { "id" : 2, "comment" : "ko" } }
{ "_id" : ObjectId("5b8d449d21edbcdd7f3b3d27"), "a" : "ok", "eps" : { "id" : 1, "comment" : "ok too" } }

标准比赛后

> db.dumb.aggregate({$match:{a:'ok'}},{$unwind:'$eps'},{$match:{'eps.id':1}})
{ "_id" : ObjectId("5b8d447b21edbcdd7f3b3d24"), "a" : "ok", "eps" : { "id" : 1, "comment" : "ok" } }
{ "_id" : ObjectId("5b8d449d21edbcdd7f3b3d27"), "a" : "ok", "eps" : { "id" : 1, "comment" : "ok too" } }
于 2018-09-03T14:38:45.013 回答
0
db.users.aggregate(

// Pipeline
[
    // Stage 1
    {
        $unwind: {
            path : "$episodes",
            preserveNullAndEmptyArrays : false // optional
        }
    },

    // Stage 2
    {
        $match: {
            "season_number" : 19.0,
            "episodes.episode_number" : 1
        }
    },

    // Stage 3
    {
        $group: {
            "_id":"$_id",
            "season_number" :{$last:"season_number"}, 
            "name" :{$last:"name"}, 
            "number_of_episodes" :{$last:"number_of_episodes"},
            "episodes":{$push:"$episodes"}
        }
    },
]);
于 2018-09-03T15:38:11.930 回答