mongoose findOne()返回所有值而不是一个值

vyu0f0g1  于 12个月前  发布在  Go
关注(0)|答案(2)|浏览(135)

我正在使用nodejs/express和mongoose处理一个端点。端点应该只返回找到的ID,如下所示:

{
    "id": 3000,
    "group": 3,
    "title": "",
    "start_time": "2023-07-31T11:00:00.000Z",
    "end_time": "2023-07-31T20:00:00.000Z",
    "category": "green"
}

字符串
然而,当我测试(localhost:3000/API/one/3000)时,它返回了属于用户的所有值,而不仅仅是一个:

{
    "_id": "658",
    "schedule": [
        {
            "events": [
                {
                    "id": 3000,
                    "group": 3,
                    "title": "",
                    "start_time": "2023-12-01T11:00:00.000Z",
                    "end_time": "2023-12-01T20:00:00.000Z",
                    "category": "green",
                },
                {
                    "id": 3001,
                    "group": 3,
                    "title": "",
                    "start_time": "2023-12-02T11:00:00.000Z",
                    "end_time": "2023-12-02T20:00:00.000Z",
                    "category": "green",
                },
                {
                    "id": 3002,
                    "group": 3,
                    "title": "",
                    "start_time": "2023-12-03T11:00:00.000Z",
                    "end_time": "2023-12-03T20:00:00.000Z",
                    "category": "green",
                },
                {
                    "id": 3003,
                    "group": 3,
                    "title": "",
                    "start_time": "2023-12-04T11:00:00.000Z",
                    "end_time": "2023-12-04T20:00:00.000Z",
                    "category": "green",
                },
                {
                    "id": 3004,
                    "group": 3,
                    "title": "",
                    "start_time": "2023-12-07T11:00:00.000Z",
                    "end_time": "2023-12-07T20:00:00.000Z",
                    "category": "green",
                }
]
        }
    ]
}


这就是mongo schema:

import mongoose, { model, Schema } from "mongoose";

const eventSchema = new mongoose.Schema({
  id: Number,
  group: Number,
  title: String,
  start_time: Date,
  end_time: Date,
  category: String,
});

const individualSchema = new mongoose.Schema({
  name: String,
  events: [eventSchema],
});

const ScheduleSchema = new mongoose.Schema({
  schedule: [individualSchema],
});

export default model("Schedule", ScheduleSchema);


这是我认为findOne()缺少的功能:

export const getById = async (req, res) => {
  try {
    const id = req.params.id;
    const found = await ScheduleSchema.findOne(
      { "schedule.events.id": id },
      { "schedule.events.$": 1 }
    );

    res.json(found);
  } catch (error) {
    console.log(error);
    console.error(error);
  }
};


我如何修复它,使它只返回给定的ID?

xdnvmnnf

xdnvmnnf1#

你可能会喜欢这样的聚合:

db.collection.aggregate([
{
 "$match": {
  "schedule.events.id": 3000
 }
},
{
"$project": {
  "schedule": {
    "$map": {
      "input": "$schedule",
      "as": "s",
      "in": {
        "events": {
          "$filter": {
            "input": "$$s.events",
            "as": "e",
            "cond": {
              "$eq": [
                "$$e.id",
                3000
              ]
            }
          }
        }
      }
    }
   }
  }
 },
 {
 "$replaceRoot": {
   "newRoot": {
     $mergeObjects: "$schedule"
     }
    }
  },
  {
   "$replaceRoot": {
     "newRoot": {
      $mergeObjects: "$events"
    }
   }
  }
 ])

字符串
解释:
1.匹配至少包含一个id=3000的嵌套对象的文档
1.只Map/过滤id=3000的匹配嵌套对象
1.使用2x replaceRoot使对象变平,以便仅获得嵌套对象
Playground

ogq8wdun

ogq8wdun2#

我认为根据你的文档设计,最好的方法是通过使用聚合和使用结果对象来模拟findOne,如下所示:

export const getById = async (req, res) => {
   try {
      const id = req.params.id;
      const agg = await ScheduleModel.aggregate([
         {
            $match: {
               "schedule.events.id": id
            }
         },
         {
            $unwind: "$schedule"
         },
         {
             $unwind: "$schedule.events"
         },
         {
            $match: {
               "schedule.events.id": id
            }
         },
         {
            $replaceRoot: {
               newRoot: "$schedule.events"
            }
         }
      ]);
      const found = agg[0]; //< Use the 0 indexed object since aggregate returns an array.

      res.json(found);
   } catch (error) {
      console.log(error);
      console.error(error);
   }
};

字符串
有关聚合的工作示例,请参见HERE

备注:为了清楚起见,我使用ScheduleModel作为执行查询的模型的名称。将模型命名为ScheduleSchema可能会使将来使用此答案的初学者感到困惑。

相关问题