2016-05-18 18 views
1

у меня есть следующие схемы mongoose:Мангуст массив срез, в заселенном поле

Главным является userSchema, который содержит массив друзей, friendSchema. Каждый friendSchema является объектом, который содержит массив messageSchema. messageSchema - это самый глубокий объект, содержащий тело сообщения.

var messageSchema = new mongoose.Schema({ 
    ... 
    body: String 
}); 

var conversationsSchema = new mongoose.Schema({ 
    ... 
    messages: [messageSchema] 
}); 

var friendSchema = new mongoose.Schema({ 
    user: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'User', 
    }, 
    conversation: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'Conversation', 
    }, 
}, { _id : false }); 


var userSchema = new mongoose.Schema({ 
    ... 
    friends: [friendSchema] 
}); 

При получении друга конкретного пользователя, я заселить свои друг профили, а если разговор есть, я тоже заселить разговор. Как я могу отрезать массив conversations.messages, который находится в населении объекта conversation? Я не хочу возвращать все сообщения.

var userId = req.userid; 
    var populateQuery = [{ path:'friends.user', 
         select: queries.overviewConversationFields }, 
         { path:'friends.conversation' }]; 

    User 
    .find({ _id: userId }, { friends: 1 }) 
    .populate(populateQuery) 
    .exec(function(err, result){ 
    if (err) { next(err); } 
    console.log(result); 
    } 

РЕДАКТИРОВАТЬ (1): Я пытался

.slice('friends.conversation.messages', -3) 

РЕДАКТИРОВАТЬ (2): Я пытался в заселить запросе

{ path:'friends.conversation', options: { 'friends.conversation.messages': { $slice: -2 } } 

РЕДАКТИРОВАТЬ (3): Для теперь я могу добиться того, что хочу, нарезая массив после выполнения запроса. Это не оптимизировано.

+0

предела массива как в? Не могли бы вы быть более конкретными. –

+0

Поскольку массив содержит весь разговор между двумя пользователями, я хотел бы получить только 25 последних сообщений, например: – FrenchFalcon

+0

http: // stackoverflow.com/questions/28514790/how-to-set-limit-for-array-size-in-mongoose-schema –

ответ

1

Немного обходной путь, который работает. Я не нашел, как $slice массив, который находится в заполненном поле.

Однако, оператор $slice работает perfecly на любой array, пока его родительский документ has'nt был заполнен.

1) я решил обновить conversationSchema, добавив массив, содержащий оба пользователя Id, участвующих в разговоре:

var conversationsSchema = new mongoose.Schema({ 
    users: [type: mongoose.Schema.Types.ObjectId], 
    messages: [messageSchema] 
}); 

2) Тогда, я могу легко найти каждый разговор мой пользователь участвует в , Как я уже сказал, я могу правильно нарезать массив messages, потому что ничего не нужно заполнять.

Conversation.find({ users: userId }, 
        { 'messages': { $slice: -1 }}, function(err, conversation) { 
}); 

3) Наконец все, что нужно сделать, чтобы запросить все друзья и разговоры по отдельности, и положить обратно все вместе, с простой петлей и _find. Это было бы сделать больше или меньше по методике, аналогичной в Монго population

Использование async.parallel для большей эффективности:

размера
async.parallel({ 
     friends: function(done){ 
     User 
      .find({ _id: userId }, { friends: 1 }) 
      .populate(populateQuery) 
      .exec(function(err, result){ 
      if (err) { return done(err);} 
      done(null, result[0].friends); 
     }); 
     }, 
     conversations: function(done){ 
     Conversation.find({ users: userId }, { 'messages': { $slice: -1 }}, function(err, conversation) { 
      if (err) { return done(err); } 
      done(null, conversation) 
     }); 
     }}, function(err, results) { 
      if (err) { return next(err); } 

      var friends = results.friends; 
      var conversations = results.conversations; 

      for (var i = 0; i < friends.length; i++) { 
      if (friends[i].conversation) { 
       friends[i].conversation = _.find(conversations, function(conv){ 
       return conv._id.equals(new ObjectId(friends[i].conversation)); 
       }); 
      } 
      } 

     }); 
     // Friends contains now every conversation, with the last sent message. 
Смежные вопросы