MongoDB:如何在同一数据库中搜索多个集合并返回混合结果集?

Mor*_*ger 4 javascript mongodb node.js sails.js waterline

我有一个单页应用程序,它使用我在 Node.js 上运行的 JavasScript 编写的 API,并使用 MongoDB 进行数据存储。该 API 公开了几种不同的内容类型,每种内容类型都存储在我的 MongoDB 数据库中的单独集合中。我的单页应用程序有一个搜索栏,其中包含一个用于选择内容类型的下拉列表(每个内容类型对应于我的 MongoDB 数据库中的一个不同集合)和一个用于指定将应用的搜索查询的输入字段。

我想要做的是:在我的下拉列表中添加一个名为“全部”的选项,当选择此选项时,我的 API 将返回五个最近创建的文档,无论包含这些文档的集合如何。

因此,举个例子,我可能有以下集合:

  • 汽车
  • 飞机
  • 自行车

我想在我的 API 中编写 JavaScript,返回其中最近的五个。因此,如果用户搜索“G”,我生成的 JSON 响应可能包含每个集合中的多个文档,如下所示:

 [
   {
     "_id": "123",
     "name": "Golf,
     "collection: "Automobile",
     "createdAt": "2014-06-20T01:45:00.0000Z"
   },
   {
     "_id": "234",
     "name": Gulfstream",
     "collection": "Airplane",
     "createdAt": "2014-06-19T01:45:00.0000Z"
   },
   {
     "_id": "345",
     "name": "Glastron",
     "collection": "Boat",
     "createdAt": "2014-06-18T01:45:00.0000Z"
   },
   {
     "_id": "456",
     "name": "Gary Fisher",
     "collection" "Bicycle",
     "createdAt": "2014-06-17T01:45:00.0000Z"
   }
   {
     "_id": "567",
     "name": "Grand Prix",
     "collection": "Automobile",
     "createdAt": "2014-06-16T01:45:00.0000Z"
   }
 ]
Run Code Online (Sandbox Code Playgroud)

问题:在 Mongo 中是否可以跨多个集合进行搜索?如果可以,我该怎么做?

请注意:

  1. 这是一个与尝试在 Mongo 中进行 JOIN 非常不同的问题——或者,至少可能是这样。(请参阅:MongoDB - 搜索多个集合。我并不像在 JOIN 中那样尝试关联来自不同集合的文档。(例如,不能说 Boats 集合中的文档包含有关 Automobiles 集合中文档的详细信息。 )
  2. 似乎有一个糟糕的解决方案,需要对每个集合运行查询(即查询五辆汽车、五架飞机、五艘船和五辆自行车;将结果合并到一个数组中,按 createAt 排序,然后拼接阵列前面的前五个)。请参阅:Meteor.js - 对多个集合进行用户搜索的方法。但是,如果可能的话,我想避免这种情况,因为 (i) 它会使查询效率降低 5 倍;(ii) 这将使分页变得非常困难。
  3. 我使用 Sails.js 作为我的框架(因此,Waterline 作为我的 ORM)。因此,即使这在 Mongo 层不可能实现,我也推测它可能已在 ORM 层实现。是这样吗?如果是这样,我将如何使用它?

Mor*_*ger 5

尽管 John Petrone 的评论非常有帮助(因为它指出我在 Mongo 中遇到了限制),但我确实想整理一份可能的解决方案的全面列表:

  1. 对每个集合运行查询(即查询五辆汽车、五架飞机、五艘船和五辆自行车;将结果合并到一个数组中,按createdAt排序,然后拼接数组前面的前五个)。(有关此解决方案的更多详细信息,请参阅上面的问题)。
  2. 根据上面 John Petrone 的评论,将所有这些类型的对象存储在同一个集合中。
  3. 通过仅存储生成搜索结果所需的每个文档的数据副本来对数据进行非规范化;所有此类副本,无论其源文档存储在哪个集合中,都可以保存在一个集合中(例如,称为 SearchResults),并且我的 SPA 中的搜索可以向 API 端点发出请求,以查询该集合中的文档。这是 John Petrone 提出的解决方案(在上面的评论中)的改编,它考虑了我使用过的 JavaScript/Mongo ORM(即 Waterline 和 Mongoose)的实际限制,如果您希望将使用不同模型构建的文档存储在同一集合中。缺点:需要对创建、更新和删除进行额外的查询;要存储更多数据;必须使 SearchResult 数据与源文档保持同步。好处:高效的读取查询;轻松与 JavaScript/Mongo ORM 兼容。