как я могу вернуть список предметов из коллекции в Mongodb, используя Node.js - PullRequest
0 голосов
/ 02 апреля 2020

Я новичок в mongodb. У меня есть пользовательские базы данных и коллекции дБ в mongodb, поэтому я пытаюсь вернуть все коллекции для конкретного пользователя. в схеме моих коллекций я связал пользователя с помощью Types.ObjectId, как показано ниже.

const CollectionsSchema = new Schema({
  user: {
    type: Schema.Types.ObjectId,
    ref: "users"
  },
  title: {
    type: String,
    trim: true
  },
  overview: { type: String },
  year: { type: String },
  poster: { type: String },
  rating: { type: Number },
  movieId: { type: Number },
  date: { type: Date, default: Date.now }
});

const Collections = mongoose.model("collections", CollectionsSchema);

module.exports = Collections;

Теперь я создаю защищенный маршрут, который возвращает коллекции для определенного пользователя, как показано ниже

router.get("/movies/:user", requireAuth, (req, res) => {
  User.findOne({ id: req.user.id }).then(user => {
    Collections.find({ user: req.params.user })
      .then(collections => {
        if (collections.user.toString() !== req.user.id) {
          return res.status(401).json({ notauthorized: "User not authorized" });
        }

        res.json(collections);
      })

      .catch(err => res.status(400).json("Error: " + err));
  });
});

Я получаю «Ошибка: Ошибка типа: не могу прочитать свойство« toString »из неопределенного», потому что у меня более одной коллекции, но когда я использую findOne (), как показано ниже

router.get("/movies/:user", requireAuth, (req, res) => {
  // const userId = req.user._id;
  User.findOne({ id: req.user.id }).then(user => {
    Collections.findOne({ user: req.params.user })
      .then(collections => {
        if (collections.user.toString() !== req.user.id) {
          return res.status(401).json({ notauthorized: "User not authorized" });
        }

        res.json(collections);
      })

      .catch(err => res.status(400).json("Error: " + err));
  });
});

Я успешно получил один предмет из своей коллекции.

Пожалуйста, как я могу использовать find (), l oop через коллекцию и вернуть все элементы в коллекции для определенного вошедшего в систему пользователя?

Благодарю вас всех в ожидании вашей помощи и времени, потраченного на изучение этого вопроса.

Цитата

Цитата

Ответы [ 2 ]

1 голос
/ 02 апреля 2020

Ваша проблема в строке:

  if (collections.user.toString() !== req.user.id)

, так как коллекции являются массивом объектов и не имеют свойства 'user'

, поэтому измените его на

router.get("/movies/:user", requireAuth, (req, res) => {
    User.findOne({ id: req.user.id }).then(user => {
        Collections.find({ user: req.params.user })
        .then(collections => {
            if (collections.findindex((obj)=>{ return obj.user.toString() !== req.user.id }) >-1) {
        return res.status(401).json({ notauthorized: "User not authorized" });
        }
    res.json(collections);
    })
   .catch(err => res.status(400).json("Error: " + err));
  });
  });

*** заметьте это! на самом деле это решает вашу проблему, но оператор if для проверки user.id здесь не нужен, потому что вы фильтровали коллекции по user.id, так что это semanti c error

лучший подход - использовать другой метод проверки авторизации или этот способ

router.get("/movies/:user", requireAuth, (req, res) => {
    User.findOne({ id: req.user.id }).then(user => {
        Collections.find({ user: req.params.user })
        .then(collections => {
            if (collections.length < 1) {
        return res.status(401).json({ notauthorized: "User not authorized" });
        }
    res.json(collections);
    })
   .catch(err => res.status(400).json("Error: " + err));
  });
  });
0 голосов
/ 02 апреля 2020

Понимание проблемы

Ошибка в том, что find() извлекает массив и findOne() извлекает объект.

посмотрите на:

Collections.find({ ... }, arg1 => { ... 
Collections.findOne({ ... }, arg2 => { ... 

В Пример выше arg1 - это массив, свойство user не существует в массиве. Следовательно, arg1.user должно вернуть undefined. Теперь понятно, почему ошибка:

"Error: TypeError: Cannot read property 'toString' of undefined"

, если arg1.user равен undefined, вы не можете позвонить arg1.user.toString().

Но в приведенном выше примере arg2 - это объект mov ie, обладающий свойством user, и оператор arg2.user.toString() прекрасно работает.

Проблема понятна, теперь давайте исправим ее.

Исправление без изменений слишком много:

router.get("/movies/:user", requireAuth, (req, res) => {
  User.findOne({ id: req.user.id }).then(user => {
    Collections.find({ user: req.params.user })
      .then(collections => {
        const data = collections.filter(c => c.user.toString() === req.user.id);

        res.json(data);
      })

      .catch(err => res.status(400).json("Error: " + err));
  });
});

Лучший подход МОЖЕТ быть (при условии, что вы пытаетесь отправить все фильмы, которые соответствуют пользователю):

router.get("/movies/:user", requireAuth, (req, res) => {
  if (req.params.user !== req.user.id) {
    return res.status(401).json({ notauthorized: "User not authorized" });
  }

  Collections
    .find({ user: req.params.user })
    .then(collections => {
      res.json(collections);
    })
    .catch(err => res.status(400).json("Error: " + err));
});

Или даже лучше: (при условии, что вы необходимо отправить все фильмы, которые может видеть зарегистрированный пользователь):

router.get("/movies/logged-user", requireAuth, (req, res) => {
  Collections
    .find({ user: req.user.id })
    .then(collections => {
      res.json(collections);
    })
    .catch(err => res.status(400).json("Error: " + err));
});

В приведенном выше фрагменте /movies/:user был изменен на /movies/logged-user

Когда : используется на express url, express сделает параметр роутера. Проверьте Express API Reference для получения дополнительной информации.

Это: /movies/:user
Совпадения: /movies/abc, /movies/123, /movies/abc123

basicaly express будет соответствовать чему-либо после /movies/ и присвоит значение req.params.user.

Но если вы хотите вернуть фильмы, которые может увидеть зарегистрированный пользователь, возможно, URL должен быть:

/movies/logged-user ТОЛЬКО соответствует этому точному URL. Здесь нет параметров маршрута, logged-user является текстом c и является частью URL.

Можно утверждать, что logged-user не является необходимым. Возможно, правильный URL должен быть:

/movies

Разница между /movies/logged-user и /movies является чисто семантической. Первый говорит явному человеку, который будет использовать api url, что фильмы, которые будут перечислены в списке, - это те, которые могут видеть зарегистрированные пользователи. Второй говорит, что будут перечислены фильмы, но не будет указано ничего другого, возможно, вводит в заблуждение идею, в которой будут перечислены все фильмы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...