简体   繁体   English

findOne 按 objectId 过滤总是返回 undefined

[英]findOne filtering by objectId always returns undefined

Developing node.js app.开发 node.js 应用程序。 For some reason this findOne call always returned undefined, even though I have verified that the req.params.id is valid and it should return data...出于某种原因,这个 findOne 调用总是返回未定义,即使我已经验证 req.params.id 是有效的,它应该返回数据......

let event = await Event.findOne({ venue: ObjectId(req.params.id) });

I've also tried....我也试过了....

let event = await Event.findOne({ venue: req.params.id });

Here's part of my model definition for Event....这是我的 Event 模型定义的一部分....

const EventSchema = new mongoose.Schema({
  eventDate: {
     type: Date
  },
  venue: {
     type: mongoose.Schema.ObjectId,
     ref: 'Venue'
  },

In postman I am doing a DELETE http verb against /venues/5e0401c4a246333ca4ced332 url for your information.在邮递员中,我正在针对/venues/5e0401c4a246333ca4ced332 url 执行DELETE http 动词以供您参考。

Basically I'm wanting to search for the venue id in the events table.基本上我想在事件表中搜索场地 ID。 I'm seeing if this venue is being used by an event before I decide to delete it.在我决定删除它之前,我正在查看该场地是否正在被某个活动使用。

Here's the entire method...这是整个方法...

// @desc    Delete venue
// @route   DELETE /api/v1/venues/:id
// @access  Private
exports.deleteVenue = asyncHandler(async (req, res, next) => {
  let venue = await Venue.findById(req.params.id);

  if (!venue) {
    return next(
      new ErrorResponse(`No venue with the id of ${req.params.id}`, 404)
    );
  }

  if (req.user.role !== 'manager' && req.user.role !== 'admin') {
    return next(new ErrorResponse(`Not authorized to delete venue`, 401));
  }

  // the following line always returns undefined even though the venue 
  // exists in the events table.... then it jumps to the end of the method
  let event = await Event.findOne({ venue: ObjectId(req.params.id) });

  if (event) {
    return next(
      new ErrorResponse(
        `You cannot delete a venue because events are tied to it.`,
        404
      )
    );
  }

  await Venue.remove();

  res.status(200).json({
    success: true,
    data: {}
  });
});

Using Compass, looking at the events collection I definitely see records using the id I submitted...使用指南针,查看事件集合,我肯定会看到使用我提交的 id 的记录......

_id:5e045b6e0c38f2502440ecb7
attendees:Array
eventDate:2020-01-01T05:00:00.000+00:00
venue:5e0401c4a246333ca4ced332
status:"planning"

I did...我做了...

  console.log(`id is ${req.params.id}`);
  let event = await Event.findOne({ venue: req.params.id });

The results showed I was passing the correct id.... (console output)结果显示我传递了正确的 id....(控制台输出)

id is 5e0401c4a246333ca4ced332
ReferenceError: Event is not defined
    at C:\Projects\abc\controllers\venues.js:90:15

Any insight would be appreciated.任何见解将不胜感激。 Thanks!谢谢!

It seems you are not importing your Event model.您似乎没有导入事件模型。 You need to add:您需要添加:

const Event = require("../models/event"); //you need to change the path 

After that you need to find the event like this: Event.findOne({ venue: req.params.id }) .之后你需要找到这样的事件: Event.findOne({ venue: req.params.id })

Also I have a few suggestions:另外我有几点建议:

1-) It makes more sense to check role authorization in the beginning. 1-) 在开始时检查角色授权更有意义。

2-) First check if there is any Event for the given Venue, and if there is no events, use findByIdAndDelete method. 2-) 首先检查给定的 Venue 是否有任何事件,如果没有事件,则使用findByIdAndDelete方法。 This way we can reduce number of db access, since we eliminated Venue.findById这样我们就可以减少数据库访问的次数,因为我们消除了Venue.findById

3-) In the case a venue has events, using a 404 status code does not seem correct. 3-) 如果场地有活动,使用 404 状态代码似乎不正确。 I think 400 - Bad request is more appropriate.我认为 400 - Bad request 更合适。

4-) mongoose converts _id's, so there is no need to use ObjectId. 4-) mongoose 会转换 _id 的,所以不需要使用 ObjectId。

exports.deleteVenue = asyncHandler(async (req, res, next) => {

  if (req.user.role !== "manager" && req.user.role !== "admin") {
    return next(new ErrorResponse(`Not authorized to delete venue`, 401));
  }

  let event = await Event.findOne({ venue: req.params.id });

  if (event) {
    return next(new ErrorResponse(`You cannot delete a venue because events are tied to it.`,400));
  }

  let venue = await Venue.findByIdAndDelete(req.params.id);

  console.log(venue);
  if (!venue) {
    return next(new ErrorResponse(`No venue with the id of ${req.params.id}`, 404));
  }

  res.status(200).json({
    success: true,
    data: {}
  });
});

Test:测试:

Let's say we have the following two Venue document.假设我们有以下两个 Venue 文件。

{
    "_id" : ObjectId("5e0471e3394d1e2b348b94aa"),
    "name" : "Venue 1",
},
{
    "_id" : ObjectId("5e0471eb394d1e2b348b94ab"),
    "name" : "Venue 2",
}

And one Event document whose venue is Venue 1 with id 5e0471e3394d1e2b348b94aa:以及一个地点为 Venue 1 且 ID 为 5e0471e3394d1e2b348b94aa 的 Event 文档:

{
    "_id" : ObjectId("5e04727c76da213f8c9bf76a"),
    "eventDate" : ISODate("2019-12-26T11:41:16.019+03:00"),
    "name" : "Event 1",
    "venue" : ObjectId("5e0471e3394d1e2b348b94aa")
}

When we want to delete the Venue 1, this will result with the following error, because it has an event:当我们要删除 Venue 1 时,这会导致以下错误,因为它有一个事件:

You cannot delete a venue because events are tied to it. with status code 400.状态码为 400。

Do it with findOneAndDelete of mongoose and Expressjs:用 mongoose 和 Expressjs 的 findOneAndDelete 来做:

const express = require("express");
const router = express.Router();

router.delete("/:id", (req, res) => {
  if (!mongoose.Types.ObjectId.isValid(req.params.id)) { //checking if id valid
    return res.send("Please provide valid id");
  }
  var id = mongoose.Types.ObjectId(req.params.id);  // passing it into a var
  Event.findOneAndDelete({ venue: id }).then( res.json({ success: true }));
});

module.exports = router;

for details https://mongoosejs.com/docs/api/query.html#query_Query-findOneAndDelete详情https://mongoosejs.com/docs/api/query.html#query_Query-findOneAndDelete

exports.deleteVenue = asyncHandler(async (req, res, next) => {

  //First check role. Because it not call database
  if (req.user.role !== 'manager' && req.user.role !== 'admin') {
    return next(new ErrorResponse(`Not authorized to delete venue`, 401));
  }

  //Next step, check event
  const event = await Event.findById({ venue: ObjectId(req.params.id) });

  if (event) {
    return next(
      new ErrorResponse(
        `You cannot delete a venue because events are tied to it.`,
        404
      )
    );
  }

  //Delete venue by Id
   await Venue.deleteOne({ id: req.params.id }, (error, result) =>{
      if(error) return next(
      new ErrorResponse(`No venue with the id of ${req.params.id}`, 404)
    );

      res.status(200).json({
         success: true,
         data: {}
       });
   })

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM