我不知道如何处理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);