Запрос MongoDB для поиска пользователя по нескольким параметрам - PullRequest
0 голосов
/ 07 октября 2018

Я понятия не имею, как обращаться с MongoDB, и я попытался и потерпел неудачу.

Проблема в следующем:

У меня есть данные, собранные с URL.Это данные: текст, местоположение, навыки, тип, hasJob, hasItem.

Эти данные, используемые для поиска пользователя в базе данных, соответствуют значениям этих параметров.

например, это URL: http://localhost:3000/profile/search/?type=exact&skills=Test,Programming&text=salam&location=uk

text=salam
type=exact
skills=[Test, Programming]
location=uk

Требуемый запрос должен делать следующее: если есть совпадающее имя, местоположение и навыки, запрос должен вернуть пользователякоторый имеет эти сопоставленные данные.Но если есть совпадающее имя, местоположение и текст без совпадений навыков, запрос также должен возвращать пользователя.

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

Это конечная точка поиска, которая должна выполнить работу:

router.get('/search', (req, res) => {
  if (!req.query || !req.query.type || (!req.query.text && !req.query.skills && !req.query.location)) {
    return res.status(400).json({status: 'bad', error: 'Missing required fields.'});
  }


  if (req.query.type !== 'fuzzy' && req.query.type !== 'exact') {
    return res.status(400).json({status: 'bad', error: 'Invalid type.'});
  }

  const user = req.user;
  const exact = req.query.type === 'exact';

  let result = [];
  let searchBuilder = {};
  let searchQuery = [];

  let locationResult =[];
  let textResult = [];
  let skillsResuts = [];
  let locationData=[];
  let textData=[];
  let skillsData= [];
  let skills =[];
  let item = {};


//1- Location
  if (req.query.location) {
      locationData = [
        {'profile.address.city': { $regex: req.query.location }},
        {'profile.address.country': { $regex: req.query.location }},
        {'profile.address.state': { $regex: req.query.location }},
        {'profile.address.zip': { $regex: req.query.location }}
    ]
    searchBuilder['$or'] = locationData;
    searchQuery.push({
        '$or': locationData
    })
  }


//2- Text
  if (req.query.text) {
      textData = [
          { 'phone': req.query.text },
          {'profile.fullName': { $regex: req.query.text }},
          {'profile.email': { $regex: req.query.text }},
          // {'profile.username': { $regex: req.query.text }}
      ]
      searchBuilder['$or'] = textData;
      searchQuery.push({
          '$or': textData
      })
  }

//3- Skills
  if (req.query.skills) {

      let allSkills = req.query.skills.split(',')
     skillsData = {
         'profile.skills.custom.name': { '$in': allSkills }
     }

     skills = allSkills.map(function(v, i){return new RegExp(v, 'i')});

      searchBuilder['profile.skills.custom.name'] = { '$in': skills }
      item = {'profile.skills.custom.name': { '$in': skills }};
      searchQuery.push({
          '$or': [ skillsData ]
      })
  }


//4. hasJobs
  if (req.query.hasJobs) {
      searchBuilder['jobs.0'] = { $exists: true };
      searchQuery.push({
          'jobs.0': { '$exists': true }
      })
  }

//5.hasItems
  if (req.query.hasItems) {
      searchBuilder['items.0'] = { $exists: true };
      searchQuery.push({
          'items.0': { '$exists': true }
      })
  }


// Add the query here 
  db.User.find({}})
    .populate('connections.user')
    .populate('jobs')
    .populate('items')
    .populate('profile.skills.custom')
    .select('-contacts')
    .sort('connections.user.profile.fullName')
    .then(users => {
      async.each(users, (user, next) => {
        if (user.id === req.user.id) {
          return next();
        }
        const check = result.find(usr => {
          return usr.id === user.id;
        });
        if (!check) {
          result.push(user);
          next();
        }
        else {
          return next();
        }
      })
    })
    .then(() => {
      res.json(result);
    })
    .catch(err => {
      return res.status(400).json({status: 'bad', error: err});
    });


});

и это схема

const UserSchema = new Schema({
  phone: String,
  shortPhone: String,
  password: String,
  profile: {
    email: String,
    fullName: String,
    username: String,
    address: {
      city: {type: String, default: 'Unknown'},
      state: String,
      country: String,
      zip: String,
    },
    photos: String,
    summary: String,
    resume: String,
    resumeFile: String,
    experiences: [{
      title: String,
      company: String,
      location: String,
      startDate: Date,
      endDate: Date,
      description: String
    }],
    educations: [{
      school: String,
      degree: String,
      field: String,
      startDate: Date,
      endDate: Date,
      description: String
    }],
    skills: {
      standard: [{type: Schema.Types.ObjectId, ref: 'Skill'}],
      custom: [{name: String}]
    },
    points: {type: Number, default: 0},
    totalPoints: {type: Number, default: 0},
    hidden: {type: Boolean, default: false},
    public: {type: Boolean, default: true},
    countryCode: String,
  },
  location: {type: [Number], index: '2d'},
  items: [{type: Schema.Types.ObjectId, ref: 'Item'}],
  blogs: [{type: Schema.Types.ObjectId, ref: 'Blog'}],
  news: [{type: Schema.Types.ObjectId, ref: 'News'}],
  conversations: [{type: Schema.Types.ObjectId, ref: 'Conversation'}],
  viewBy: [{type: Schema.Types.ObjectId, ref: 'User'}],
  level: {type: Number, default: 1},
  verified: {type: Boolean, default: false},
  notificationTokens: [{type: String}],
  connections: [{
    user: {type: Schema.Types.ObjectId, ref: 'User'},
    relationship: {type: String, enum: ['requested', 'received', 'connected']},
    isForced: {type: Boolean, default: false}
  }],
  declinedRequests: [String],
  jobs: [{type: Schema.Types.ObjectId, ref: 'Job'}],
  favoritedJobs: [{type: Schema.Types.ObjectId, ref: 'Job'}],
  sharedJobs: [{type: Schema.Types.ObjectId, ref: 'Job'}],
  viewedJobs: [{type: Schema.Types.ObjectId, ref: 'Job'}],
  favoritedItems: [{type: Schema.Types.ObjectId, ref: 'Item'}],
  sharedItems: [{type: Schema.Types.ObjectId, ref: 'Item'}],
  viewedItems: [{type: Schema.Types.ObjectId, ref: 'Item'}],
  actions: [{type: Schema.Types.ObjectId, ref: 'Action'}],
  incentives: [{type: Schema.Types.ObjectId, ref: 'Incentive'}],
  contacts: [String],
  synced: {type: Boolean, default: false}
});

//UserSchema.plugin(autoPopulateAllFields);

exports.User = mongoose.model('User', UserSchema);
...