Как обновить свойство объекта, находящегося внутри массива, с помощью мангуста

Итак, у меня есть messageThread со ссылкой на группу сообщений.

var messageThreadSchema = new Schema({
    chatBetween: [{ type: Schema.Types.ObjectId, ref: 'User' }],
    messages: [{ type: Schema.Types.ObjectId, ref: 'Message' }],
    lastMessage: {type: String}
})

Соответственно, у меня есть схема message

var messageSchema = new Schema({
    sender: { type: Schema.Types.ObjectId, ref: 'User' },
    reciever: { type: Schema.Types.ObjectId, ref: 'User' },
    sentAt: { type: Date, default: Date.now },
    text: String,
    isRead: { type: Boolean, default: false }
})

У меня проблема с обновлением message.isRead через messageThread.

Мне нужно обновить свойство isRead всех сообщений внутри messageThread


Я пытался:

1.

 MessageThread.findByIdAndUpdate(req.body._id, {
  $set: {"messages.$.isRead": true} // I thought, maybe there is a typo and 
  "$set": {"messages.$.isRead": true} // tried too
  "$set": {"messages.$.isRead": "true"} // tried too
  })
  .populate({ path: "messages" })
  .exec((err, foundMessageThread) => {

});

2.

Как добавить обновление и удалить объект в Схема массива в Mongoose/MongoDB

MessageThread.update({'_id': req.body._id},
  {'$set': {
         "messages.$.isRead": true
   }},
      function(err,model) {
    if(err){
        console.log(err);
        return res.send(err);
    }
    return res.json(model);
});

3.

Тогда я решил обновить isRead вручную. Я имею в виду:

MessageThread.findById(req.body._id)
  .populate({ path: "messages" })
  .exec((err, foundMessageThread) => {
    var updatedMessage = foundMessageThread.messages.map(message=>{
        return {...message, isRead:true}
    })
    var newThread = {...foundMessageThread, 
    messages: [...foundMessageThread.messages, ...updatedMessage]}
    newThread.save()
  });

Конечно, это не работает в Node. Поэтому мне пришлось все переделывать с помощью Object.assign(), что сделало мой код еще более запутанным.((

Мой вопрос:

  1. Почему мои 1 и 2 методы не работают?
  2. Есть ли способ проще?

person m_rd_n    schedule 03.01.2018    source источник
comment
Можете ли вы передать messageThread._id и message._id функции, найти messageThread, а затем findByIdAndUpdate message?   -  person Chau Tran    schedule 03.01.2018
comment
Вы пытаетесь обновить коллекцию, отличную от коллекции, для которой выполняется обновление. Обновления MongoDB предназначены только для данных в одной коллекции. Правильным способом было бы управлять отношениями отдельно и синхронизировать их. Этот должен прояснить для вас ситуацию. Его для удаления, но концепция аналогична.   -  person s7vr    schedule 03.01.2018
comment
@ChauTran, вы правы, я мог бы просто найти message._id и изменить isRead, но я думаю, что это отрицательно скажется на производительности. Потому что могут быть миллионы сообщений, не связанных с пользователем. Я прав?   -  person m_rd_n    schedule 03.01.2018
comment
@Veeram, кажется, я не смог тебя достать. Не могли бы вы уточнить? Когда дело доходит до примера, он прекрасно объясняет, но я не смог найти связи с моим случаем. Я имею в виду, что в моем случае я не хочу обновлять messageThread, вместо этого, заполняя его, я хочу, чтобы message обновлял их. Как я могу обновить их, не просматривая миллионы сообщений?   -  person m_rd_n    schedule 03.01.2018
comment
Как показывает ваш messageSchema, один messageThread принадлежит только двум общающимся пользователям, не так ли? Вы только от flagRead до message.receiver === currentUser.id && !message.isRead, и вы можете выполнить проверку на стороне клиента с помощью другого сервиса, чтобы получить currentUser. Я не думаю, что это будет саботировать ваше выступление, в крайнем случае, не настолько, чтобы это заметили. Сообщения messageThread представляют собой массив messageId, поэтому вам НЕ НУЖНО делать здесь какие-либо изменения, если только вы не реализуете удаление сообщений.   -  person Chau Tran    schedule 03.01.2018
comment
Еще одна вещь, на которую следует обратить внимание: у Mongoose есть Hooks, которые вы можете использовать как pre и post, поэтому вы можете иметь schema.pre('update', ...) или schema.post('update'...) для изменения других вещей, связанных с соответствующим обновлением сообщения.   -  person Chau Tran    schedule 03.01.2018
comment
@ChauTran, да, messageThread принадлежит двум Users и имеет отношения «один-многие» с message. И я согласен, мне не нужно изменять messageThread. Что вы имеете в виду под flagRead?   -  person m_rd_n    schedule 03.01.2018
comment
Просто метод, который я использую в своем приложении, чтобы пометить сообщение как прочитанное (в вашем случае установите для isRead значение true).   -  person Chau Tran    schedule 03.01.2018
comment
Давайте продолжим обсуждение в чате.   -  person Chau Tran    schedule 03.01.2018