Задать вопрос
@japan123

Как из одной коллекции выбрать данные в другой?

есть endpoint /search, на который приходят данные от фильтров от одного, или от двух и больше или не приходят вовсе в случае, если фильтры не заданы, в соответствии с пришедшими данными формируем объект query для запроса к БД.
app.post('/search', function(req, res) {
        //все жилье по умолчанию (занятое и свободное)
        var query = {}
        var filter = {}

        //price
        if (req.body.min && req.body.max) {      
            query.cost_per_night = {$gte: req.body.min, $lte: req.body.max}
            //по возрастанию
            filter.cost_per_night = 1
        }
        //dates
        if (req.body.from && req.body.to) {
            query.reserved = { 
            //все свободное жилье
                
                $not: {
                    $elemMatch: {from: {$lt: new Date(req.body.to)}, to: {$gt: new Date(req.body.from)}}
                }
            }
        }
        if (req.body.guests > 1) {
            query.occupancy = {$gte: req.body.guests}
        }
        if (req.body.search) {
            query.city = { $regex: req.body.search.toLowerCase() }
        }
        Nomer
            .find(query)
            .sort(filter)
            .then(function (err, result) {
                if(err){
                    res.send(err);
                } else {
                    res.json(result);
                }
            })
    })

Раньше все лежало в одной схеме и проблем с выборкой не было. Но теперь я сделал две схемы Reservation и Nomer.
const reservationSchema = mongoose.Schema({
  nomer: { type: ObjectId, ref: 'Nomer' },
  from: { type: Date },
  to: { type: Date },
}

const nomerSchema = mongoose.Schema({
  type: String,
  beds: Number,
  reservations: [{ type: ObjectId, ref: 'Reservation' }],
  occupancy: {
      type: Number,
      default: 1,
  },
  owner: {
    type: ObjectId,
    ref: 'User'
  },
  cost_per_night: Number

Проблема: если пришли данные from и to, как сделать выборку всех незанятых номеров как и раньше и при этом, если данные от других фильтров пришли, чтобы все вместе работало?
  • Вопрос задан
  • 121 просмотр
Подписаться 2 Простой 4 комментария
Пригласить эксперта
Ответы на вопрос 2
@Lebed71
Node.js Developer
Смотрите в сторону Aggregation Framework, в частности на оператор $lookup. Но он весьма слабоват, поэтому вполне возможно что придётся делать два запроса к базе и процессить данные ручками в коде.
Ответ написан
@lega
Я бы сделал простой запрос по индексу (from-to) - получить все занятые на период. И уже на бекенде (из кеша или монги) выдал бы все что не попали в список (т.к. номеров не много).
Это один из самых производительных вариантов. А сложные запросы и запросы с отрицанием (not) часто приводят к полному перебору.

PS: но для учебного проекта не факт что подойдет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы