Учебное пособие, которое мы, новички, можем понять
Если вы читали какой-либо из моих нескольких постов, то знаете, что я младший программист на стажировке. Если вы не просматривали ни одну из моих публикаций, я младший программист на стажировке. Я посещаю The Iron Yard Charleston, и мы собираемся по уши в изучении баз данных и углублении. Росту прилива усугубляет определенная техническая документация, которая не всегда очень удобна для новичков, таких как я. Я смотрю на тебя, Мангуст. Ты красивая, непрозрачная вещь ты.
Моя последняя проблема была связана с использованием нескольких коллекций для сайта в стиле социальных сетей. Одна коллекция для пользователей и одна для сообщений. В своем исследовании, прежде чем приступить к программированию, я наткнулся на Model.populate (), метод Mongoose, который можно использовать для существенного связывания документов между коллекциями. Это позволяет вам иметь схему для каждого из них и, как правило, сохранять все в порядке и порядке.
Это должно было быть легко, и, честно говоря, это так! Но в большинстве руководств, которые я читал по нему, не учитывался один крошечный шаг, из-за которого я потратил около пяти часов впустую. Это почти наверняка из-за моей неопытности, поэтому я собираюсь пройти очень простые детские шаги в надежде помочь другому начинающему программисту, вроде меня, избежать потраченных впустую часов.
Шаг 1. Создайте схемы
Вам нужна схема для каждой коллекции. Один для пользователей и один для сообщений, которые они собираются делать.
const UserSchema = new mongoose.Schema({ username: String, posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }] }) const PostSchema = new mongoose.Schema({ content: String, author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' } }) const Post = mongoose.model('Post', PostSchema, 'posts'); const User = mongoose.model('User', UserSchema, 'users'); module.exports = { User, Post, }
Свойства, для которых мы хотим использовать .populate (), являются свойствами, имеющими тип mongoose.Schema.Types.ObjectId. Это говорит Mongoose: «Эй, я буду ссылаться на другие документы из других коллекций». Следующая часть этого свойства - исх. Ссылка сообщает Mongoose: «Эти документы будут в коллекции ___».
Итак, в нашей схеме User мы ссылаемся на коллекцию Post, потому что мы хотим, чтобы пользователь был привязан к тому, что он публикует, и мы хотим иметь возможность легко получать доступ к этим сообщениям без необходимости создавать дополнительные запросы.
На этом наши схемы установлены.
Шаг 2. Правильное создание пользователей и сообщений
Чтобы документы правильно подключались при последующем заполнении, вам нужно понять одну, очень простую вещь, о которой никто никогда прямо не заявлял, пока я искал в Интернете помощь по этому поводу. После связывания других коллекций в вашей схеме с использованием соответствующего type и ref ваши фактические сохраненные данные для этого свойства будут _id другого документа . Он будет сохранен в виде строки. Это также работает для массива _ids.
Итак, пока ваша схема говорит это:
const UserSchema = new mongoose.Schema({ username: String, posts: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Post' }] })
Фактическое сохраненное свойство должно выглядеть примерно так:
{ _id: 59ab1c92ea84486fb4ba9f28, username: JD, posts: [ "59ab1b43ea84486fb4ba9ef0", "59ab1b43ea84486fb4ba9ef1" ] }
Имейте в виду, что это ваш сохраненный документ . Мы еще не вызывали для него .populate (). Как только он будет вызван, он перейдет в соответствующую коллекцию, найдет эти два _id и вернет вашего пользователя, но теперь с массивом его фактических сообщений. Давай сделаем это сейчас.
Шаг 3. Реализация .Populate ()
Вот функция:
function getUserWithPosts(username){ return User.findOne({ username: username }) .populate('posts').exec((err, posts) => { console.log("Populated User " + posts); }) }
.populate () нуждается в запросе для присоединения, поэтому мы используем User.findOne (), чтобы найти пользователя, который соответствует имени пользователя, которое мы указываем в аргументе. Это возвращает наш пользовательский документ. Это когда .populate () берет верх. Вы заметите, что я отправляю «сообщения» в наш .populate (). Предоставляя аргумент «posts», мы сообщили .populate (), с каким свойством в нашем пользовательском документе мы хотим, чтобы оно работало. Вызов .exec () просто выполняет что-то после того, как .populate () сделал это. В журнале печатается это:
{ _id: 59ab1c92ea84486fb4ba9f28, username: 'JD', posts: [ { _id: 59ab1b43ea84486fb4ba9ef0, content: "Is it dark out?" },{ _id: 59ab1b43ea84486fb4ba9ef1, content: "Hey anyone got a cup of sugar?" } ] }
И, как по волшебству, мы создали единый объект, используя 2 схемы, 2 модели и 2 коллекции. Все шаги, конечно, важны, но то, что ни один другой сайт не дал явного разъяснения, заключалось в том, что после настройки наземных работ вы должны убедиться, что вы вводите _ids в поле, которое вам нужно будет заполнить позже.