0

У меня есть две коллекции в MongoDB: одна сохраняет данные в блоге, другая сохраняет данные комментариев в блоге с помощью нижеприведенных схем. Как я могу использовать nodejs и mongoose для запроса всех сообщений с комментариями к нему и отвечать на одностраничное приложение ?. Благодаря!запрос по многим отношениям mongodb database struct

var PostSchema = mongoose.Schema({ 
    created: { 
     type: Date, 
     default: Date.now 
    }, 
    content: { 
     type: String, 
     default: '', 
     trim: true 
    }, 
    user: { 
     type: Schema.ObjectId, 
     ref: 'user' 
    } 
}); 

var CommentSchema = mongoose.Schema({ 
    created: { 
     type: Date, 
     default: Date.now 
    }, 
    content: { 
     type: String, 
     default: '', 
     trim: true 
    }, 
    ofpost: { 
     type: Schema.ObjectId, 
     ref: 'post'   //which post this comment belong to 
    }, 
    user: { 
     type: Schema.ObjectId, 
     ref: 'user' 
    } 
}); 




    var Post = mongoose.model('Post', PostSchema); 
    var Comment = mongoose.model('Comment', CommentSchema); 

//example:the Comment1 and Comment2 belong to Post1 
    var Post1 = new Post({ content: 'good day', user: 'John' }); 
    var Comment1 = new Comment({content: 'yeah', ofpost: Post1._id, user:'Tom'}) 
    var Comment2 = new Comment({content: 'agree', ofpost: Post1._id, user:'Tina'}) 
+0

Не могли бы вы немного пояснить 'ref: 'post'' в' CommentSchema'. –

+0

Hi @Amol M Kulkarni, я создаю две модели на вышеприведенных схемах: var Post = mongoose.model ('Post', PostSchema); var Комментарий = mongoose.model ('Comment', CommentSchema); И это две коллекции: var Post1 = new Post ({content: 'good day', user: 'John'}); var Комментарий1 = новый Комментарий ({content: 'yeah', ofpost: Post1._id, пользователь: 'Tom'}) var Comment2 = new Комментарий ({content: 'agree', ofpost: Post1._id, user: ' Tina '}) Итак, Comment1 и Comment2 принадлежат Post1 –

+0

Согласно вашим комментариям 'var Post1 = new Post ({content:' good day ', user:' John '});' не имеет ** '_id' * * поле; Но вы используете его как ссылку, 'var Comment1 = new Comment ({content: 'yeah', ofpost:' ** 'Post1._id' **', user: 'Tom'}); '. Исправьте его в своей схеме и обновите в своем вопросе. –

ответ

1

Как MongoDB является NoSQL тип базы данных и не имеет JOIN «с или какой-либо связи между документами, вы должны заботиться о таких.
Существует два способа сделать это:

Кэширования
Рассмотрит хранение данных комментариев в блоге документа. У вас могут быть встроенные документы без каких-либо проблем. На самом деле это приводит к некоторым дополнительным кэшам, таким как количество комментариев, массив идентификаторов пользователей и другие материалы, которые будут индексировать ваши запросы и более простые способы поиска по коллекции.

Несколько запросов
Если вам еще нужны отдельные коллекции, то вам нужно «симулировать» присоединяется. Наиболее эффективными способами являются временные массивы индексирования и несколько запросов к различным коллекциям. Обычно это должно быть всего 2 запроса для одного Join (многие для многих) и небольшая итерация для добавления вторых документов запроса в первый массив документов.

Здесь поток, который подходит и хорошо работает до сих пор, на примере:
Две коллекции, первый это posts, а второй является comments который имеет id столба.

  1. Сделать запрос к сообщениям.
  2. Итерация по каждому сообщению и добавить его в idpostIds массиве, а также сделать postMap объект, где key будет id столба и value будет конкретными post. - это так называемые индексирующие сообщения.
  3. Сделать запрос к comments коллекции с $in аргумент с postIds массив сообщений id. Эта коллекция должна индексировать поле post id, чтобы сделать этот запрос очень эффективным. Также этот запрос может включать сортировку по дате (добавление дополнительных индексов ускорит его).
  4. Итерации через каждый комментарий и использование postMap добавьте его в комментарии массив сообщений.

Таким образом, у нас есть только 2 запроса и одна итерация по всем комментариям для вставки данных в сообщения O (n). Без второго шага добавление в сообщения будет потенциально O (p * c), где p - количество сообщений и c - количество комментариев. Который, очевидно, намного медленнее, а также при больших запросах, может быть потенциально медленным.

Резюме
Второй подход более управляем подход с точки зрения данных, а также легче на writes, в то время как более сложные по reads.
По-прежнему потребуется некоторое кэширование, как и количество комментариев к сообщениям в блоге.

+0

Кэширование: хорошо, но это невозможно, если у нас есть 1000 комментариев к сообщению Несколько запросов: Это то, что я делаю, но я использую nodejs для серверной части, и Процесс nodejs - это асинхронный процесс, мы ничего не можем добавить, как вы говорите, «используя postMap, добавьте его в массив комментариев публикации». Давайте взглянем на мою проблему: [link] (https://github.com/LearnBoost/mongoose/issues/1706) –

+0

Еще одна ссылка: [link] (http://stackoverflow.com/questions/18950984/return- value-from-asynchronous-function-in-nodejs) –

+0

Над ссылками, я использую человека вместо сообщения, а продукт вместо комментария. Один человек может купить много видов продуктов. –

Смежные вопросы