猫鼬:find()-匹配两个值并仅返回匹配的文档

时间:2018-09-03 14:04:17

标签: javascript mongodb mongoose mongodb-atlas

我环顾四周,但找不到解决该问题的确切方法。我浏览了Mongoose文档,并试图找到一种方法。我是MongoDB的新手,并希望在遵循大量教程之后创建自己的API。

目标:

http://localhost:3000/seasons/19/1的GET请求 并返回系列详细信息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...*
]

3 个答案:

答案 0 :(得分:1)

您可以使用聚集上的 $ 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起可用

答案 1 :(得分:0)

编辑:使用$ filter

最初找到了解决方案here

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 })

与意甲匹配(此处称为“确定”)

> 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" } }

答案 2 :(得分: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"}
        }
    },
]);