如何一次从多个Mongo集合中查询(查找)并合并结果

时间:2019-08-25 23:46:44

标签: mongodb mongoose collections promise

我想从彼此不相关的多个集合中获取结果。我正在创建一个搜索引擎,该引擎将使用一个术语,传递给后端,并对多个集合(书籍,作者,标签)进行查询/查找,然后将它们组合成一个对象以返回。这些集合中没有任何外键关系,我只想查找与文本项匹配的结果。

但是,我很难找到正确的解决方案。我用来执行查找查询的模型返回了一个Promise,所以我想找到一种正确检索的方法,因为它是异步的。

我尝试了Promise.all方法,但最终失败并显示500错误,因为我知道我做错了。

router.post('/', (req, res, next) => {
   var results = {}, term = req.body.term;

   var authors = Authors.find().or([
                           {first_name: new RegExp(term, 'i')},
                           {last_name: new RegExp(term, 'i')}
                       ]);
   var books = Books.find().or([
                           {title: new RegExp(term, 'i')},
                           {author: new RegExp(term, 'i')},
                           {description: new RegExp(term, 'i')}
                       ]);
   var tags = Tags.find().or([
                           {name: new RegExp(term, 'i')}
                       ]);

   Promise.all([authors, books, tags])
       .then(results => res.send(results));        
});

我想从所有集合中获取结果,并能够将其组合到单个JSON对象中。像这样:

{
    books: {
          // results from Books collection
    },
    authors: {
          // results from Authors collection
    },
    tags: {
          // results from Tags collection
    },
}

1 个答案:

答案 0 :(得分:0)

使用异步等待,并且理想情况下发出router.get请求而不是router.post

router.get('/', async (req, res) => {
   let term = req.body.term;

   let authors = await Authors.find().or([
                       {first_name: new RegExp(term, 'i')},
                       {last_name: new RegExp(term, 'i')}
                   ]);
   let books = await Books.find().or([
                       {title: new RegExp(term, 'i')},
                       {author: new RegExp(term, 'i')},
                       {description: new RegExp(term, 'i')}
                   ]);
   let tags = await Tags.find().or([
                       {name: new RegExp(term, 'i')}
                   ]);
    let results = {
                   authors,
                   books,
                   tags
                  }  

     res.send(results));        
   });