我是使用node,express和mongodb的新手,所以我不知道这是否是实现此目的的最佳方法,我在电影商店(仅供学习和练习)工作,用户将在其中拥有工具栏顶部带有搜索栏,可以进行常规搜索以查找电影/电视剧/其他电影,现在我以为可以在byte[]
中用express
实现此功能的方式是这样:
mongoose
所以这里的想法是在多个集合之间进行搜索,正如您所看到的,我所做的只是在一个集合中进行搜索,这是对Promise在另一个集合中进行搜索的响应。现在,我完全确定这不是一个好方法,如果我想在10个不同的集合之间进行搜索将是一个非常混乱的代码,那么有没有更好的方法来实现这一目标。
答案 0 :(得分:3)
在没有依赖项时,您可以使用Promise.all
而不是链式诺言。
let moviesPromise = Movie.find({ name: { $regex: req.body.query, $options: 'i' } });
let seriesPromise = Serie.find({ name: { $regex: req.body.query, $options: 'i' } });
Promise.all([moviesPromise, seriesPromise]).then((res) => {
arr = ['movies', 'series'];
res.map((e, i)) => {
e.map(obj => {
return {
_id: obj._id,
content_type: obj.content_type,
rate: obj.rate,
name: obj.name,
item_img: obj.[`${arr[i]}_img`],
itemType: arr[i]
};
});
})
答案 1 :(得分:2)
您可以创建一个包含要在其中查找的模型和名称的数组(因为您的img
字段基于名称),然后循环遍历并使用async/await
查找:
router.post('/search', async (req, res) => {
try {
let resultSearch = [];
let sets = [{model: Movie, name: 'movie'}, {model: Serie, name: 'serie'}, ...some more];
for (let set of sets) {
let results = await set.model.find({ name: { $regex: req.body.query, $options: 'i' } });
results = results.map(result => {
return {
_id: result._id,
content_type: result.content_type,
rate: result.rate,
name: result.name,
item_img: result[`${set.name}_img`],
itemType: set.name //or you can use set.model.collection.collectionName
};
})
resultSearch = resultSearch.concat(results);
}
res.status(200).send(resultSearch);
} catch(err) {
console.log(error);
res.status(500).send(error);
}
})
更新:按照AZ_的建议,使用Promise.all
然后将输出映射到预期的响应将提供更好的性能:
router.post('/search', async (req, res) => {
try {
let sets = [{model: Movie, name: 'movie'}, {model: Serie, name: 'serie'}, ...some more];
let resultSearch = await Promise.all(sets.map(set => set.model.find({ name: { $regex: req.body.query, $options: 'i' } }).exec()));
resultSearch = resultSearch.map((results, i) => {
return results.map(result => {
return {
_id: result._id,
content_type: result.content_type,
rate: result.rate,
name: result.name,
item_img: result[`${sets[i].name}_img`],
itemType: sets[i].name //or you can use sets[i].model.collection.collectionName
};
})
}
res.status(200).send(resultSearch.flat()); //resultSearch is 2D array so need to flatten it
} catch(err) {
console.log(error);
res.status(500).send(error);
}
})