Есть ли лучший подход для фильтрации данных при вызове GET, как показано ниже? (NodeJs и MongoDb) - PullRequest
0 голосов
/ 06 августа 2020

Итак, у меня есть ряд пользователей, например:

let person1 = {
  username: 'test',
  userId: '11',
  log: [
    {
      _id: '5f2b29f501ec0e46c7f2944c',
      date: 'Tue Feb 02 2010',
      duration: 34,
      description: 'tennis 2010',
    },
    {
      _id: '5f2b2a888878e94706a6f072',
      date: 'Fri Feb 02 2001',
      duration: 23,
      description: 'tennis',
    },
    {
      _id: '5f2b2a8d8878e94706a6f073',
      date: 'Sat Feb 02 2002',
      duration: 23,
      description: 'tennis',
    },
    {
      _id: '5f2b2a918878e94706a6f074',
      date: 'Sun Feb 02 2003',
      duration: 23,
      description: 'tennis',
    },
  ],
};


Я хотел бы позвонить, используя GET /api/exercise/log?{userId}[&from][&to][&limit], где [] параметры являются необязательными, а {} требуется.

, поэтому, если даты каждого журнала:

'Sat Feb 02 2002'

'Sat Feb 02 2003'

'Sat Feb 02 2004'

'Sat Feb 02 2005'

и мой вызов /api/exercise/log?userId=11&from=2003-03-01 Результатом должны быть журналы, в которых был выполнен вход

'Sat Feb 02 2004'

'Sat Feb 02 2005'

Все, что ниже, работает хорошо и это дает мне то, что я хочу, я просто хотел бы знать, есть ли лучшая практика для фильтрации с использованием запросов.

app.get('/api/exercise/log?', (req, res) => {
  const { userId, from, to, limit } = req.query;

  //   if userId was entered
  if (userId) {
    //   find person
    Exercise.findOne({ userId })
      .then((person) => {
        let result = [];
        // if "from" was entered
        if (from) {
          // return only the date that are greater than "from"
          person.log.map((exercise) => {
            if (new Date(exercise.date).valueOf() >= new Date(from).valueOf()) {
              result.push(exercise);
            }
          });
          return result;
        } else {
          // else return all the logs
          return person.log;
        }
      })
      .then((logs) => {
        let result = [];
        // if "to" was entered
        if (to) {
          // return only the date that are less than "to"
          logs.map((exercise) => {
            if (new Date(exercise.date).valueOf() <= new Date(to).valueOf()) {
              result.push(exercise);
            }
          });
          return result;
        } else {
          // else return all the logs
          return logs;
        }
      })
      .then((logs) => {
        let result = [];

        // if limit was entered
        if (limit) {
          for (let i = 0; i < limit; i++) {
            result.push(logs[i]);
          }
          return result;
        } else {
          // if limit wasn't entered, return all the logs
          return logs;
        }
      })
      .then((logs) => {
         // render result
        res.send(logs);
      }).catch(err=>{
        // if user doesn't exist
        res.send('Unknown User')
      })
  } else {
         // if userId wasen't entered
    res.send('unknown user');
  }
});


1 Ответ

0 голосов
/ 06 августа 2020

В первую очередь вы должны сформулировать свой запрос так, чтобы он возвращал только интересующие данные, но давайте придерживаться указанного подхода.

После нахождения person вся обработка полностью синхронна, поэтому три .then(logs => ....) этапы могут быть объединены в начальный .then(person => ...) этап, что позволяет написать что-то вроде этого:

app.get('/api/exercise/log?', (req, res) => {
    const { userId, from, to, limit } = req.query;
    if (userId) {
        Exercise.findOne({ userId }) // find person
        .then(person => {
            let filtered = person.log.filter((exercise, i) => {
                let exerciseDate = new Date(exercise.date);
                let from_ = from ? exerciseDate >= new Date(from) : true; // boolean for `from` condition
                let to_ = to ? exerciseDate <= new Date(to).valueOf() : true; // boolean for `to` condition
                let limit_ = i < limit; // boolean for `limit` condition
                return from_ && to_ && limit_; // will return `true` only if all three conditions are met. 
            });
            res.send(filtered);
        })
        .catch(err => {
            res.send('Unknown User');
        });
    } else {
        res.send('unknown user');
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...