MongoDB findOne (), возвращающий пустой массив вложенных документов - PullRequest
1 голос
/ 23 марта 2020

Я использую Mon goose и MongoDB v. 6.4.1. Я определил коллекцию документов со встроенными вложенными документами, используя следующие схемы Mon goose:

import mongoose, { Collection } from 'mongoose';
const connectStr = 'mongodb://localhost/appdb';
mongoose.set('useFindAndModify', false);

//Open connection to database
mongoose.connect(connectStr, {useNewUrlParser: true, useUnifiedTopology: true})
  .then(
    () =>  {console.log(`Connected to ${connectStr}.`)},
    err => {console.error(`Error connecting to ${connectStr}: ${err}`)}
  );

//Define schema that maps to a document in the Users collection in the appdb
//database.
const Schema = mongoose.Schema;

const roundSchema = new Schema({
  date: {type: Date, required: true},
  course: {type: String, required: true},
  type: {type: String, required: true, enum: ['practice','tournament']},
  holes: {type: Number, required: true, min: 1, max: 18},
  strokes: {type: Number, required: true, min: 1, max: 300},
  minutes: {type: Number, required: true, min: 1, max: 240},
  seconds: {type: Number, required: true, min: 0, max: 60},
  SGS: {type: Number, 
        default: function(){return (this.strokes * 60) + (this.minutes * 60) + this.seconds}
       },
  notes: {type: String, required: true}
});

const userSchema = new Schema({
  id: {type: String, required: true}, //unique identifier for user
  password: String, //unencrypted password (for now!)
  displayName: {type: String, required: true}, //Name to be displayed within app
  authStrategy: {type: String, required: true}, //strategy used to authenticate, e.g., github, local
  profileImageUrl: {type: String, required: true}, //link to profile image
  rounds: [roundSchema],
  securityQuestion: {type: String},
  securityAnswer: {type: String, required: function() {return this.securityQuestion ? true: false}}
});

//Convert schema to model
const User = mongoose.model("User",userSchema); 

В маршруте Express. js GET, я использую следующий код для запроса определенного c document:

try {
    let thisUser = await User.findOne({id: req.params.userId});
    console.log("thisUser: " + JSON.stringify(thisUser));
    if (!thisUser) {
      return res.status(400).send("No user account with specified userId was found in database.");
    } else {
      return res.status(200).json(thisUser.rounds);
    }
  } catch (err) {
    console.log(err);
    return res.status(400).message("Unexpected error occurred when looking up user in database: " + err);
  }

Мой оператор console.log подтверждает, что вышеприведенный маршрут фактически получает желаемый документ, например:

thisUser: {"_id":"5e6704234f3864318caedd12","id":"chundhau@gmail.com","password":"GoCougs20","displayName":"chundhau@gmail.com","authStrategy":"local","profileImageUrl":"https://www.gravatar.com/avatar/4b565c54d37b3f5ad4caa1c129e865b8","securityQuestion":"First pet?","securityAnswer":"Daisy","__v":0,"rounds":[]}

Когда я смотрю на этот же документ в Сообщество MongoDB Compass, я могу подтвердить, что его массив субдокументов rounds имеет несколько элементов:

MongoDB Compass Community Screeenshot

Однако, как показано в выводе console.log выше , rounds возвращается как пустой массив . Я подтвердил, что (a) rounds на самом деле является массивом (с использованием Array.isArray()) и что (b) rounds не имеет элементов (thisUser.rounds.length === 0).

Разве я не могу получить доступ ко всем вложенным документам через thisUser.rounds? Что я сделал не так?

1 Ответ

1 голос
/ 23 марта 2020

Я нашел решение. Я изменил:

let thisUser = await User.findOne({id: req.params.userId});

на

let thisUser = await User.findOne({id: req.params.userId}).lean();

Чудесным образом, thisuser.rounds больше не был пустым. Вместо этого он содержал все элементы массива, которые я мог видеть при проверке документа в MongoDB Compass Community!

Пока это решение работало, я не знаю , почему это работало. Если бы кто-нибудь мог помочь мне понять, что здесь происходит, я был бы признателен за это!

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