简体   繁体   English

Model.find({}) 返回空,即使集合中有文档

[英]Model.find({}) returns empty even though there are documents in the Collection

I am able to write to the users collection using my '/sign-up' route - that works fine, but I cannot read all the documents from the users collection.我可以使用我的 '/sign-up' 路由写入users集合 - 工作正常,但我无法读取用户集合中的所有文档。 All I get back is an empty array我得到的只是一个空数组

{
    "status": "success",
    "results": 0,
    "data": {
        "users": []
    }
}

In mongo shell I am able to get back all the users like db.users.find().pretty()在 mongo shell 中,我能够找回所有用户,例如db.users.find().pretty()

{
        "_id" : ObjectId("5f95ad29c2b3fc4f1876bb83"),
        "role" : "student",
        "photo" : "default.jpg",
        "active" : true,
        "name" : "Orion POC",
        "email" : "vega@example.com",
        "password" : "$2a$12$xpO3cloW5H.n650i0xQXEuaZOfdvTt43Y2dkMxrY5K8zfGfPIUYEO",
        "passwordChangedAt" : ISODate("2020-10-25T16:51:52.600Z"),
        "__v" : 0
}

Solution Tried尝试解决方案

  • I have added collection as an property in the second argument that you can pass in mongoose.Schema() to make it target the pluraised collection name - because utils.toCollectionName我在第二个参数中添加了集合作为属性,您可以传入 mongoose.Schema() 以使其以复杂集合名称为目标 - 因为utils.toCollectionName

I am honestly at wits end here, I don't know what the problem is, and its the same for other Collections as well老实说,我在这里无能为力,我不知道问题是什么,其他Collections也一样

models/userModel.js模型/userModel.js

const crypto = require('crypto');
const mongoose = require('mongoose');
const validator = require('validator');
const bcryptjs = require('bcryptjs');

const userSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, 'You must have a name'],
      minlength: [5, 'A name must have more than 5 characters'],
      maxlength: [30, 'A name cannot have more than 30 characters'],
    },

    email: {
      type: String,
      required: [true, 'You must have an email'],
      maxlength: [50, 'The email entered is too long'],
      unique: true,
      lowercase: true,
      validate: [validator.isEmail, 'Your email is not valid'],
    },

    role: {
      type: String,
      enum: ['student', 'parent', 'teacher'],
      default: 'student',
    },

    photo: {
      type: String,
      default: 'default.jpg',
    },

    password: {
      type: String,
      required: [true, 'You must give a password'],
      minlength: [
        8,
        'Your password is too short, you must enter more than 8 characters',
      ],
      validate: [
        function (val) {
          const regex = RegExp('^[-\\w@!$£%^&*+]+$');
          return regex.test(val);
        },
        'Non-special characters are not allowed, please use a mix of letters and numbers',
      ],
      select: false,
    },

    passwordConfirm: {
      type: String,
      required: [true, 'Please confirm your password'],
      minlength: [
        8,
        'Your password is too short, you must enter more than 8 characters',
      ],
      validate: [
        function (val) {
          return val === this.password;
        },
        'Password do not match',
      ],
      select: false,
    },

    active: {
      type: Boolean,
      default: true,
      select: false,
    },

    // Field is only given to a user when they have changed their password, if not this field will not exist in the user document
    passwordChangedAt: Date,
    passwordResetToken: String,
    passwordResetExpires: Date,
  },
  {
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
    collection: 'users',
  }
);

// SCHEMA MIDDLEWARE

// hash password
userSchema.pre('save', async function (next) {
  if (!this.isModified('password')) return next();

  // hash and salt password with cost of 12
  this.password = await bcryptjs.hash(this.password, 12);

  // delete passwordConfirm field
  this.passwordConfirm = undefined;

  next();
});

// create timestamp for a changed password
userSchema.pre('save', function (next) {
  if (!this.isModified('password')) return next();

  // Subtract 1000ms for error margins
  this.passwordChangedAt = Date.now() - 1000;
  next();
});

// Retrieve only active users
userSchema.pre(/^find/, function (next) {
  this.find({ active: { $ne: true } });
  next();
});

// INSTANCE METHODS

// Password checker
userSchema.methods.correctPassword = async function (
  inputPassword,
  userPassword
) {
  return await bcryptjs.compare(inputPassword, userPassword);
};

// Check if the password has been modified
userSchema.methods.modifiedPassword = function (JWTTimestamp) {
  if (this.passwordChangedAt) {
    const changedTimeStamp = parseInt(
      this.passwordChangedAt.getTime() / 1000,
      10
    );

    // Password HAS been changed
    return JWTTimestamp < changedTimeStamp;
  }
  // Password has NOT been changed
  return false;
};

// Set the passwordResetToken
userSchema.methods.createPasswordResetToken = function () {
  const resetToken = crypto.randomBytes(32).toString('hex');
  this.passwordResetToken = crypto
    .createHash('sha256')
    .update(resetToken)
    .digest('hex');

  // console.log({ resetToken }, this.passwordResetToken);

  this.passwordResetExpires = Date.now() + 10 * 60 * 1000;

  return resetToken;
};

const User = mongoose.model('User', userSchema);
module.exports = User;

controllers/userController.js控制器/userController.js

const multer = require('multer');
const sharp = require('sharp');

const User = require('../models/userModel');
const catchAsync = require('../utils/catchAsync');
const AppError = require('../utils/appError');
const factory = require('./handlerFactory');

exports.getAllUsers = catchAsync(async (req, res, next) => {
  const users = await User.find({});
  console.log(users);

  res.status(200).json({
    status: 'success',
    results: users.length,
    data: {
      users,
    },
  });
});

routes/userRoutes.js路线/userRoutes.js

const express = require('express');
const userController = require('../controllers/userController');
const authController = require('../controllers/authController');

// ROUTING
const router = express.Router();

router.post('/sign-up', authController.signup);

router.get('/', userController.getAllUsers);

router.get('/:id', userController.getUser);

module.exports = router;

app.js应用程序.js

const express = require('express');
const morgan = require('morgan');
const rateLimit = require('express-rate-limit');
const helmet = require('helmet');
const mongoSanitize = require('express-mongo-sanitize');
const xss = require('xss-clean');
const hpp = require('hpp');
const cors = require('cors');
const cookieParser = require('cookie-parser');
const compression = require('compression');

const userRouter = require('./routes/userRoutes');
const globalErrorHandler = require('./controllers/errorController');
const AppError = require('./utils/appError');

const app = express();

// app.use(
//   cors({
//     origin: 'http://127.0.0.1:3000',
//     credentials: true,
//   })
// );

// SET Security HTTP headers
app.use(helmet());
// app.use(
//   helmet.contentSecurityPolicy({
//     directives: {
//       defaultSrc: ["'self'", 'https:', 'http:', 'data:', 'ws:'],
//       baseUri: ["'self'"],
//       fontSrc: ["'self'", 'https:', 'http:', 'data:'],
//       imgSrc: ["'self'", 'data'],
//       scriptSrc: ["'self'", 'https:', 'http:', 'blob:'],
//       styleSrc: ["'self'", "'unsafe-inline'", 'https:', 'http:'],
//     },
//   })
// );

// dev logging
if (process.env.NODE_ENV === 'development') {
  app.use(morgan('dev'));
}

// Limit number of requests from the same IP
const limiter = rateLimit({
  max: 100,
  windowMs: 60 * 60 * 1000,
  message: 'Too many requests from this IP, please try again in an hour!',
});

app.use('/api', limiter);

// body parser, reading data from body into req.body
// middleware that sits in the middle of req(uests) and res(ponse) - we do this to get access to the body of a HTTP request
app.use(express.json({ limit: '10kb' }));
app.use(cookieParser());

// Data sanitization against NoSQL query injections
app.use(mongoSanitize());

// Data sanitization against XSS
app.use(xss());

// Protect against request parameter pollution
app.use(
  hpp({
    whitelist: [
      'duration',
      'ratingsQuantity',
      'ratingsAverage',
      'maxGroupSize, ',
      'difficulty',
      'price',
    ],
  })
);

// TO COMPRESS ALL INCOMING TEXT REQUEST AND COMPRESS THEM USING GZIP ETC.
app.use(compression());

// ROUTES
app.use('/api/v0/users', userRouter);

// UNHANDLED ROUTE ERROR MIDDLEWARE
app.all('*', (req, res, next) => {
  next(new AppError(`Can't find ${req.originalUrl} on this server!`, 400));
});

// GLOBAL ERROR HANDLER MIDDLEWARE: SIGNATURE (ERROR, REQ, RES, NEXT)
app.use(globalErrorHandler);

module.exports = app;

server.js服务器.js

const mongoose = require('mongoose');
const dotenv = require('dotenv');

// CATCH ERRORS THAT ARE NOT PROMISE RELATED
process.on('uncaughtException', (err) => {
  console.log('UNHANDLED EXCEPTION! Shutting down...');
  // console.log(err.stack);
  console.log(err.name, err.message);
  process.exit(1);
});

// READ IN ENV VARS INTO SERVER
dotenv.config({ path: './config.env' });
const app = require('./app');

// PLACE PASSWORD IN MONGO CONNECTION STRING
const DB = process.env.DATABASE.replace(
  '<PASSWORD>',
  process.env.DATABASE_PASSWORD
);

// CONNECT TO CLOUD MONGODB
mongoose
  .connect(DB, {
    useNewUrlParser: true,
    useCreateIndex: true,
    useFindAndModify: true,
    useUnifiedTopology: true,
    autoIndex: true,
  })
  .then((con) => console.log('DB Connection Successful'));

// START SERVER
const port = process.env.PORT || 3000;
const server = app.listen(port, () => {
  console.log(`App running on port ${port}...`);
});

// CATCH UNHANDLED PROMISES
process.on('unhandledRejection', (err) => {
  console.log('UNHANDLED REJECTION! Shutting down...');
  console.log(err.name, err.message);
  server.close(() => {
    process.exit(1);
  });
});

// FOR HEROKU ON THEIR 24/7 SIGTERM SIGNAL
// process.on('SIGTERM', () => {
//   console.log('🖐 SIGTERM RECEIVED. Shutting down gracefully...');
//   server.close(() => {
//     console.log('🧨 Process terminated!');
//   });
// });

thank you for the comments - it my first time writing a question to Stackoverflow.感谢您的评论 - 这是我第一次向 Stackoverflow 写问题。 I am sorry for the very long code snippets - I will try to look at the minimal code example and in the future post questions like that.对于很长的代码片段,我很抱歉 - 我将尝试查看最小的代码示例,并在以后发布类似的问题。

I re-wrote the code for my Users, I literally re-wrote it code-for-code, and magically like that, User.find() worked.我为我的用户重新编写了代码,我逐字逐句地重新编写了它,神奇地是,User.find() 成功了。

I am sorry for the waste of time anyone had got from this.对于任何人因此而浪费的时间,我深表歉意。

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

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