Невозможно добавить массив в документе MongoDB (mongoose)

#node.js #arrays #mongodb #mongoose #passport.js

#node.js #массивы #mongodb — монгодб #mongoose #passport.js

Вопрос:

Я пытаюсь добавить пустой массив в базу данных mongo со строкой, которая создается во внешнем интерфейсе (пользовательский интерфейс веб-сайта), соответствующие фрагменты кода следующие:

схема mongoose

     email: String,
    displayName: String,
    googleId: String,
    toIgnore: [{toIgnoreURL: String}]
})
  

создание документа с помощью passport amp; паспорт-google-oauth20

 User.findOne({email: email.emails[0].value}).then((currentUser)=>{
            if(currentUser){
                // user does already exist
                console.log('welcome back!', currentUser)
                done(null, currentUser)
            }
            else{ // user doesn't exist yet
            new User({
                email: email.emails[0].value,
                displayName: email.displayName,
                googleId: email.id,
                toIgnore: []
            }).save().then((newUser)=>{
                console.log('new user created: '   newUser)
                done(null, newUser)
            });
            }
        })
  

И, наконец, попытка добавить свойство массива toIgnore из коллекции ‘User’ (текущего пользователя, вошедшего в систему)

 User.update(
        {email: emailThisSession},
        {$push: {toIgnore: {toIgnoreURL: url}}})
  

В mongodb я вижу, что следующий документ успешно создан

 _id
:ObjectId(
IdOfDocumentInMongoDB)
toIgnore
:
Array
email
:
"myactualtestemail"
googleId
:
"longgoogleidonlynumbers"
__v
:
0
  

(Также, как видно на прикрепленном изображении)
документ в пользовательском интерфейсе mongodb

Кажется, я не понимаю, как на самом деле заполнить массив ‘toIgnore’. Например, когда консоль регистрирует следующее

 var ignoreList = User.findOne({email:emailThisSession}).toIgnore;
console.log(ignoreList)
  

Вывод undefined
Обратите внимание, что консоль, регистрирующая переменную url, действительно выводит значение, которое я хочу добавить к массиву!
Я пробовал любую комбинацию форматов, какую только мог придумать в построителе схем и создании документов, но я не могу найти правильный способ сделать это!
Будем признательны за любую помощь!

Обновление, использование promises также не сработало

 User.findOne({email:emailThisSession}).then((currentUser)=>{ //adding .exec() after findOne({query}) does not help as in User.findOne({email:emailThisSession}).exec().then(...)
            console.log(currentUser.toIgnore, url) //output is empty array and proper value for url variable, empty array meaning []
            currentUser.toIgnore.push(url)
        });
  

При настройке схемы следующим образом:

 const userSchema = new Schema({
    email: String,
    displayName: String,
    googleId: String,
    toIgnore: []
})
  

Решение

Мне просто нужно было изменить команду update на

 User.updateOne(
            {email: emailThisSession},
            {$push: {toIgnore: {toIgnoreURL: url}}}).then((user)=>{
                console.log(user)
            })
  

Спасибо @yaya!

Ответ №1:

Невозможно добавить элемент массива в документ с помощью mongoose

  1. определите вашу схему как:
 const UserSchema = new mongoose.Schema({
  ...
  toIgnore: [{toIgnoreURL: String}]
})
  
  1. затем вы можете создать объект, подобный этому :
 new User({
  ...,
  toIgnore: [] // <-- optional, you can remove it
})
  
  1. Для проверки значения:
 User.findOne({...}).then(user => {
  console.log(user.toIgnore)
});
  
  1. Ваше заявление об обновлении должно быть:
 User.update(
  {email: emailThisSession},
  {$push: {toIgnore: {toIgnoreURL: url}}}
).then(user => {
  console.log(user)
})
  

Итак, в вашем случае это не определено:

 User.findOne({email:emailThisSession}).toIgnore
  

Поскольку findOne является асинхронным. для получения результата вы можете либо передать ему обратный вызов, либо использовать promises ( User.findOne({...}).then(user => console.log(user.toIgnore)) )

Обновить:

При настройке схемы следующим образом: new Schema({..., toIgnore: []})

Вот проблема с вашим обновлением. вы должны изменить его обратно на : toIgnore: [{toIgnoreURL: String}]

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

1. @Hope2Code в вашем обновлении возникла проблема. обновлен ответ.

2. Мне удалось напечатать пустой массив, как в списке игнорирования с помощью кода var ignoreList = User.findOne({email:emailThisSession}).then((currentUser)=>{ console.log(currentUser.toIgnore, url) currentUser.toIgnore.push(url) }); , но я все еще не могу добавить массив с помощью .push

3. @Hope2Code смотрите обновление. ваша схема неверна, поэтому она не сохраняет обновленное значение. сначала исправьте свою схему, затем снова вызовите update user , чтобы она снова сохранила обновленное значение.

4. @Hope2Code теперь я вижу другую проблему. User.update(...) не выполняется, вы должны выполнить это вручную. например, с помощью : User.update(...).then(user => {console.log(user)}) или с .exec()

5. Схема @Hope2Code верна. но updateOne этого не делает. then означает execute the statement and get the result. . так что это должно быть: User.updateOne( {email: emailThisSession}, {$push: {toIgnore: {toIgnoreURL: url}}}).then((user)=>{console.log('done', user)})