我怎样才能用 mongodb 编写这个查询? [复制]

Posted

技术标签:

【中文标题】我怎样才能用 mongodb 编写这个查询? [复制]【英文标题】:how can i write this query with mongodb? [duplicate] 【发布时间】:2017-04-22 13:32:59 【问题描述】:

我想用 mongodb 写这个查询

select   * 
from     tab1 a, tab2 c 
where    a.a_id = 2 
and      c.c_id = 3 
and      a.a_id = c.c_fk_account_id_created_by

我尝试了这段代码,但没有得到响应:

$cursor = $collection->find(array('$and' => array(array("a_id" => 2), array("c_id" => 3))));

【问题讨论】:

【参考方案1】:

我假设你有两个集合,分别命名为 tab1 和 tab2,格式为

标签1

    
        "_id" : ObjectId("58482a97a5fa273657ace535"), 
        "a_id" : NumberInt(2)
    

tab2

 
    "_id" : ObjectId("58482acca5fa273657ace539"), 
    "c_id" : NumberInt(3), 
    "c_fk_account_id_created_by" : NumberInt(2)

您将需要一个包含两个步骤的聚合查询,首先,$lookup 到第二个表,第二个 $match 在正确的键上。像这样。

db.tab1.aggregate(
[
    
        $lookup: 
            "from" : "tab2",
            "localField" : "a_id",
            "foreignField" : "c_fk_account_id_created_by",
            "as" : "c"
        
    ,
    
        $match: 
            "a_id": 2,
            "c.c_id": 3             
        
    ,
]

);

这会给你这样的输出

 
"_id" : ObjectId("58482a97a5fa273657ace535"), 
"a_id" : NumberInt(2), 
"c" : [
    
        "_id" : ObjectId("58482acca5fa273657ace539"), 
        "c_id" : NumberInt(3), 
        "c_fk_account_id_created_by" : NumberInt(2)
    
]

祝你好运!

【讨论】:

我喜欢@Joshua 的回答,我建议使用它。只是为了展示一种不同的方式......你也会得到这样的答案:db.tab1.find().forEach( function (object) var join=db.tab2.findOne( c_fk_account_id_created_by: object._id, _id: 3 ); if (join != null) // here are the matches printjson(join) ; else // no match, nothing to do ); MBushveld,这实际上也是一种有趣的方法。至少值得为学习机会而努力。【参考方案2】:

我写了一篇关于这种查询的文章:

用于 T-SQL 专业人士的 MongoDB 聚合框架 #3:$lookup 运算符 https://www.linkedin.com/pulse/mongodb-aggregation-framework-t-sql-pros-3-lookup-operator-finch

基本上,您将使用 $lookup 聚合运算符将第二个表中的所有文档放入第一个表的结果中。然后,您可以使用 $match 和 $group 运算符来过滤和汇总您的数据。

它会变成这样:

db.tab1.aggregate([
   $match:
        "tab1.a_id": 2 
,
   $lookup:
       from: "tab2",
        localField: "a_id",
        foreignField: "c_fk_account_id",
        as: "tab2_results"
     
,
   $match:
        "tab2_results.c_id": 3 

]

匹配的连接文档将作为数组添加到基表的文档中。它充当左连接,因为远程表中的空值被忽略,您的基表文档仍然返回,只是缺少远程数据。

希望这会有所帮助!

比尔

【讨论】:

在 $lookup 之前匹配 a_id 很好,我尽可能地效仿他的例子,但这是正确的做法!【参考方案3】:

假设 tab1 和 tab2 有 3 个字段,分别为 a_idaa1aa2c_idc_fk_account_id_created_bycc1

查询如下

db.tab1.aggregate([$match:a_id:2,$lookup:from:'tab2', localField:'c_fk_account_id_created_by', foreignField:'a_id', as:'ccArray',$unwind:'$ccArray', $project:a_id:1,aa1:1, aa2:1, c_id:'$ccArray.c_id',c_fk_account_id_created_by:'$ccArray.c_fk_account_id_created_by',cc1:'$ccArray.cc1',$match:c_id:3])

上述查询的解释: 由于 MongoDB 不允许从聚合管道中的第二个表匹配,所以我们必须展开第二个表数组并比较值

select * from tab1 a, tab2 c where a.a_id = 2 ==> $match:a_id:2 and c.c_id = 3 ==> (Cannot be done at first so it can be acheived as ) ==> $unwind:'$ccArray', $project:a_id:1,aa1:1, aa2:1, c_id:'$ccArray.c_id',c_fk_account_id_created_by:'$ccArray.c_fk_account_id_created_by',cc1:'$ccArray.cc1',$match:c_id:3 and a.a_id = c.c_fk_account_id_created_by ==> $lookup:from:'tab2', localField:'c_fk_account_id_created_by', foreignField:'a_id', as:'ccArray'

【讨论】:

以上是关于我怎样才能用 mongodb 编写这个查询? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

我怎样才能摆脱这个 MongoDB 错误? mongoose MongoNotConnectedError: MongoClient must be connected to perform this

php操作mongoDB数据库查询的时候怎样写“或”这样的多个条件查询代码?

为啥这个 pg 查询这么慢?我怎样才能让它更快?

我如何编写一个从 mongodb 查询的辅助函数,然后可以为任何 ejs 模板调用此函数

我怎样才能重复这个查询 100 次?

我怎样才能做这个多重 JOIN 查询?