常规搜索:在多个馆藏之间搜索(快速/猫鼬)

时间:2019-08-27 07:43:52

标签: node.js mongodb express mongoose

我是使用node,express和mongodb的新手,所以我不知道这是否是实现此目的的最佳方法,我在电影商店(仅供学习和练习)工作,用户将在其中拥有工具栏顶部带有搜索栏,可以进行常规搜索以查找电影/电视剧/其他电影,现在我以为可以在byte[]中用express实现此功能的方式是这样:

mongoose

所以这里的想法是在多个集合之间进行搜索,正如您所看到的,我所做的只是在一个集合中进行搜索,这是对Promise在另一个集合中进行搜索的响应。现在,我完全确定这不是一个好方法,如果我想在10个不同的集合之间进行搜索将是一个非常混乱的代码,那么有没有更好的方法来实现这一目标。

2 个答案:

答案 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);
  }
})
相关问题