Пн goose | NodeJS: Как добавить два «ref» к одному и тому же модельному термину и заполнить его? - PullRequest
0 голосов
/ 15 января 2020

ОБНОВЛЕНО: Я попробовал это:

  ad:[{ type: mongoose.Types.ObjectId, ref: 'Ad' }],
  car:[{ type: mongoose.Types.ObjectId, ref: 'Car' }]

Это работает, но я не могу заказать, поэтому, все еще застрял ..

.populate('ad')
.populate('car')
.sort({createdAt:-1}) 

(Я хотел бы заказать по созданному или обновленному времени)

Вот что я пробовал до следующего:

Я действительно застрял, и я тоже знаю, что мне просто нужна небольшая помощь, чтобы решить это.

Я работаю nodeJS и над проектом HBS (веб-сайт в качестве craigslist).

У меня есть разные модели, для разных изломов категории: вакансии имеют свой собственный вид, автомобили имеют свой собственный вид и так далее .. .

У меня есть модель пользователя, в которой содержится каждое опубликованное объявление.

const userSchema = new Schema({
  email:{
    type:String,
    required:true,
    trim:true,
    lowercase:true,
    match: [/\S+@\S+\.\S+/, 'is invalid']
  },
  password:{
    type:String,
    required:true,
    trim:true
  },
  ad:[{ type: mongoose.Types.ObjectId, ref: 'Ad'},{ type: mongoose.Types.ObjectId, ref:'Car'}]
}, {
  timestamps: {
    createdAt: "created_at",
    updatedAt: "updated_at"
  }
});

Как видите, у меня есть это:

ad:[{ type: mongoose.Types.ObjectId, ref: 'Ad'},{ type: mongoose.Types.ObjectId, ref:'Car'}]

В моем пн goose база данных, я могу сохранить эти данные через $ pu sh:

.then(ad => {
            User.updateOne({email:ad.email},{$push:{ad:ad._id}})
            .then(() => res.render('ads/test'))
          })

Все работает, mongodb:

//mongodb database
> db.users.find().pretty()
{
    "_id" : ObjectId("5e1e28663128e9643c523712"),
    "ad" : [
        ObjectId("5e1e28633128e9643c523711"),
        ObjectId("5e1e28733128e9643c523713")
    ],
    "email" : "whatever@whatever.com",
    "password" : "$whatever$whatever.whatever",
    "created_at" : ISODate("2020-01-14T20:45:26.262Z"),
    "updated_at" : ISODate("2020-01-14T20:45:39.694Z"),
    "__v" : 0
}

Итак, у меня есть два объявления из разных модели (модель A: публикация категории работ, модель B: публикация категории автомобилей) и их идентификаторы:

"ad" : [
            ObjectId("5e1e28633128e9643c523711"),
            ObjectId("5e1e28733128e9643c523713")
        ]

После этого в моем пользовательском контроллере я пытаюсь заполнить ... но я просто т в одной модели:

module.exports.myAds = (req, res, next) => {
  User.findOne({email:req.session.currentUser.email})
    .populate({path: 'ad', options: { sort: { 'updated_at': -1 }}})
    .then(ads => {
      console.log(ads)
      res.render('users/my-ads', { ads:ads } )
    })
    .catch(err => next(err))
}

Пожалуйста, мне нужно решить эту проблему. Что я делаю не так?

Я искал те же объяснения, но мне никто не подошел.

Я тоже пытался разделить ad на:

 ad:[{test_1:{ type: mongoose.Types.ObjectId, ref:'Ad'}},{test_2:{type: mongoose.Types.ObjectId, ref:'Car'}}]

Но даже не хороший результат. Может быть, я ошибаюсь в $ pu sh для test_1 / test_2 или даже когда я заполняюсь?

Ответы [ 2 ]

1 голос
/ 15 января 2020

Заполнить не идеально для пользователя в этой ситуации. Вы должны попытаться использовать агрегацию с оператором $ lookup, см .: https://docs.mongodb.com/manual/reference/operator/aggregation/lookup/ Таким образом вы получите больший контроль над данными

0 голосов
/ 15 января 2020

Наконец, я решил сделать это:

//ads.controller 
   // here I $push both kinds of ads (both models, ad and car) to user model


    User.findOne({email:email})
          .then(user => {
            if(user !== null){
              console.log(`User ${user.email} already exists`)
              newCarAd.save()
              .then(ad => {
                User.updateOne({email:ad.email},{$push:{car:ad._id}})
                .then(() => res.render('ads/test'))
              })
              .catch(error => {
                if (error instanceof mongoose.Error.ValidationError) {
                  renderWithErrors(error.errors)
                } else {
                  next(error)
                }
              })

// user model

    const userSchema = new Schema({
    ...

      ad:[{ type: mongoose.Types.ObjectId, ref: 'Ad' }],
      car:[{ type: mongoose.Types.ObjectId, ref: 'Car' }]
    }, {
      timestamps: {
        createdAt: "created_at",
        updatedAt: "updated_at"
      }
    });

//user controller 
//to populate and handle object from both models -pushed from 
//ads.controller-
    module.exports.myAds = (req, res, next) => {
      User.findOne({email:req.session.currentUser.email})
        .populate('ad')
        .populate('car')
        .sort({createdAt:-1})
        .then(ads => {
          //join all ads in same object to my-ads views
          const arrayUserAds = [...ads.ad,...ads.car];
  const allUserAds = arrayUserAds.sort((a,b) => {return b.updated_at -a.updated_at})

          res.render('users/my-ads', { ads:allUserAds } )
        })
        .catch(err => next(err))
    }
...