Учебное пособие, которое мы, новички, можем понять

Если вы читали какой-либо из моих нескольких постов, то знаете, что я младший программист на стажировке. Если вы не просматривали ни одну из моих публикаций, я младший программист на стажировке. Я посещаю 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 в поле, которое вам нужно будет заполнить позже.