在多个集合中搜索 mongoose

Posted

技术标签:

【中文标题】在多个集合中搜索 mongoose【英文标题】:Search in multiple collections mongoose 【发布时间】:2019-08-02 12:05:11 【问题描述】:

我有大约 15 个集合(具有不同数据结构的不同提供商),它们有一些共同的字段,比如 标题、描述和价格

我目前正在尝试使用公共字段为我的 API 实现搜索功能,并且我能够为每个集合单独执行此操作。

是否可以使用该公共字段一次查询所有 15 个集合? 一个一个做的问题是性能问题(我必须精简我的结果)以及在它上面有分页的事实。

我想创建一个具有公共字段的共享集合有点晚了。

【问题讨论】:

How do I perform the SQL Join equivalent in MongoDB?的可能重复 我建议您使用不同的数据库。尽管最近 mongo 增加了搜索功能,但搜索 15 个集合将是太多的 imo。如果您可以将集合减少到一个,它可能是相关的。 【参考方案1】:

没有办法对多个集合运行单个查询,您仍然可以做的是并行运行所有查询并等待所有结果到来,然后您可以在响应中发送集合结果。

代码应如下所示:

var promises = [];
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());
promises.push(Collection1.find(title : "title",desription : "description",...).lean().exec());

Promise.all(promises).then(results=>
    // results[0] will have docs of first query
    // results[1] will have docs of second query
    // and so on...

    // you can combine all the results here and send back in response
).catch(err=>
    //handle error here
)

【讨论】:

我想也没有办法。我只是花了几个小时查找文档并没有找到任何东西。毕竟我决定做一个共同的收藏【参考方案2】:

根据 mongo 文档,$lookup 只能加入一个外部集合。

您可以做的是将 userInfo 和 userRole 组合在一个集合中,因为提供的示例基于关系数据库模式。 Mongo 是 noSQL 数据库 - 这需要不同的文档管理方法。

请在下面找到结合 userInfo 和 userRole 的两步查询 - 创建用于上次查询的新临时集合以显示组合数据。在最后一个查询中,有一个选项可以使用 $out 并使用合并的数据创建新集合以供以后使用。

创建集合

db.sivaUser.insert(
    
"_id" : ObjectId("5684f3c454b1fd6926c324fd"),
    "email" : "admin@gmail.com",
    "userId" : "AD",
    "userName" : "admin"
)

 //"userinfo"
db.sivaUserInfo.insert(

"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"phone" : "0000000000"
)

//"userrole"
db.sivaUserRole.insert(

"_id" : ObjectId("56d82612b63f1c31cf906003"),
"userId" : "AD",
"role" : "admin"
)

聚合集合

db.sivaUserInfo.aggregate([
$lookup:
    
       from: "sivaUserRole",
       localField: "userId",
       foreignField: "userId",
       as: "userRole"
    
,

    $unwind:"$userRole"
,

    $project:
        "_id":1,
        "userId" : 1,
        "phone" : 1,
        "role" :"$userRole.role"
    
,

    $out:"sivaUserTmp"

])

db.sivaUserTmp.aggregate([
$lookup:
    
       from: "sivaUser",
       localField: "userId",
       foreignField: "userId",
       as: "user"
    
,

    $unwind:"$user"
,

    $project:
        "_id":1,
        "userId" : 1,
        "phone" : 1,
        "role" :1,
        "email" : "$user.email",
        "userName" : "$user.userName"
    

])

【讨论】:

以上是关于在多个集合中搜索 mongoose的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB搜索多个集合

MyBatis中动态sql实现传递多个参数并使用if进行参数的判断和实现like模糊搜索以及foreach实现in集合

大型字谜搜索未读取到集合 Python 的末尾

使用多个字段的 Solr 搜索查询

快速组合多个搜索字段

Java 集合的多个索引 - 最基本的解决方案?