Атлас MongoDB и Мангуст, уникальный «_id» не регистрируется как уникальный

#javascript #node.js #express #mongoose #mongodb-atlas

Вопрос:

Я пытаюсь создать новый экземпляр места для конкретного пользователя. Когда я смотрю на свой атлас MongoDB, значения «_id» для каждого пользователя фактически уникальны. Когда у меня есть один экземпляр пользователя в базе данных, я могу создать для этого пользователя столько мест, сколько захочу. Проблема возникает, когда я создаю нового пользователя, я больше не могу создавать новые места ни для одного из пользователей.

Вот ошибка, которую я получаю на интерфейсе:

places-controllers.js

 const { validationResult } = require('express-validator');
const mongoose = require('mongoose');

const getCoordsFromAddress = require('../util/location');
const HttpError = require('../models/http-error');

const Place = require('../models/place');
const User = require('../models/user');

const createPlace = async (req, res, next) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return next(
      new HttpError('Invalid inputs passed, please check your data.', 422)
    );
  }

  const { title, description, address, creator } = req.body;

  let coordinates;
  try {
    coordinates = await getCoordsFromAddress(address);
  } catch (error) {
    return next(error);
  }

  const createdPlace = new Place({
    title,
    description,
    address,
    location: coordinates,
    image: req.file.path,
    creator,
  });

  let user;
  try {
    user = await User.findById(creator);
  } catch (err) {
    const error = new HttpError(
      'Creating place failed, please try again.',
      500
    );
    return next(error);
  }

  if (!user) {
    const error = new HttpError('Could not find user for provided id.', 404);
    return next(error);
  }

  console.log(user);
  
  //THIS SEEMS TO BE THE POINT WHERE THE CODE FAILS

  try {
    const session = await mongoose.startSession();
    session.startTransaction();
    await createdPlace.save({ session: session });
    user.places.push(createdPlace);
    await user.save({ session: session });
    await session.commitTransaction();
  } catch (err) {
    console.log(err);
    const error = new HttpError(
      'Creating place failed, please try again.',
      500
    );
    return next(error);
  }

  res.status(201).json({ place: createdPlace });
};
 

Тогда вот схема:

place.js

 const mongoose = require('mongoose');

const Schema = mongoose.Schema;

const placeSchema = new Schema({
  title: { type: String, required: true },
  description: { type: String, required: true },
  image: { type: String, required: true }, //url for a database
  address: { type: String, required: true },
  location: {
    lat: { type: Number, required: true },
    lng: { type: Number, required: true },
  },
  creator: { type: mongoose.Types.ObjectId, required: true, ref: 'User' },
});

module.exports = mongoose.model('Place', placeSchema);
 

и, наконец, код ошибки:

 Error: User validation failed: _id: Error, expected `_id` to be unique. Value: `616d8a452c5215f9fafb6052`
    at ValidationError.inspect (/Users/james/Desktop/Full Stack Udemy Course (MERN)/Fullstack-app/server/node_modules/mongoose/lib/error/validation.js:48:26)
    at internal/per_context/primordials.js:23:32
    at formatValue (internal/util/inspect.js:774:19)
    at inspect (internal/util/inspect.js:336:10)
    at formatWithOptionsInternal (internal/util/inspect.js:2006:40)
    at formatWithOptions (internal/util/inspect.js:1888:10)
    at console.value (internal/console/constructor.js:313:14)
    at console.log (internal/console/constructor.js:348:61)
    at createPlace (/Users/james/Desktop/Full Stack Udemy Course (MERN)/Fullstack-app/server/controllers/places-controllers.js:112:13)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  errors: {
    _id: ValidatorError: Error, expected `_id` to be unique. Value: `616d8a452c5215f9fafb6052`
        at validate (/Users/james/Desktop/Full Stack Udemy Course (MERN)/Fullstack-app/server/node_modules/mongoose/lib/schematype.js:1277:13)
        at /Users/james/Desktop/Full Stack Udemy Course (MERN)/Fullstack-app/server/node_modules/mongoose/lib/schematype.js:1252:24
        at processTicksAndRejections (internal/process/task_queues.js:93:5) {
      properties: [Object],
      kind: 'unique',
      path: '_id',
      value: new ObjectId("616d8a452c5215f9fafb6052"),
      reason: undefined,
      [Symbol(mongoose:validatorError)]: true
    }
  },
  _message: 'User validation failed'
}
 

Любая помощь была бы очень признательна, я уже некоторое время ломаю голову над этим.

Комментарии:

1. Слепое предположение, после user.places.push(createdPlace) попытки добавления user.markModified("places"); ?

2. @JeremyThille К сожалению, нет, это не работает. Есть ли что-нибудь еще, что я должен добавить к сообщению, что могло бы помочь? Это мой первый раз, когда я прошу других людей о помощи, я не на 100% уверен, что это необходимо.

3. Я нашел это , по-видимому, это какая-то ошибка, введенная в mongoose-unique-validator версии 2.0.2…

4. Я предполагаю, что ваша ошибка происходит из строки user = await User.findById(creator); , потому что она не может получить значение создателя из req.body

5. @JeremyThille Большое спасибо, повторная прокатка мангуста и уникальный валидатор мангуста, похоже, работают. 🙂

Ответ №1:

Ответил любезно @JeremyThille.

mongoose-unique-validator в нем есть ошибка, из-за которой, когда у вас несколько пользователей, он обнаруживает ссылку _id на другую схему. Затем он решает, что _id больше не является уникальным и не позволит никому из пользователей публиковать новый документ.

Исправление на данный момент заключается в повторном прокате mongoose и mongoose-unique-validator в v^5.11.13 и v^2.0.3 соответственно.

Здесь размещена текущая проблема с GitHub.

https://github.com/blakehaswell/mongoose-unique-validator/issues/131