2

我有这个集合命名为“点”MongoDB的聚合过滤器和依靠的NodeJS

[ 
    { 'guid': 'aaa' }, 
    { 'guid': 'bbb' }, 
    { 'guid': 'ccc' }, 
] 

,我有另一个名为“流”

[ 
    { 'title': 'pippo', 'guid': 'aaa', 'email': '[email protected]'}, 
    { 'title': 'pluto', 'guid': 'aaa', 'email': '[email protected]'}, 
    { 'title': 'goofy', 'guid': 'bbb', 'email': '[email protected]'}, 
    { 'title': 'duck', 'guid': 'aaa', 'email': '[email protected]'}, 
    { 'title': 'minnie', 'guid': 'ccc', 'email': '[email protected]'}, 
] 

我需要做的,我想汇总查询搜索包含字母“o”的email。我所期望的结果是这样的

[ 
    { 'guid': 'aaa', items: 2 }, 
    { 'guid': 'bbb', item: 1 }, 
    { 'guid': 'ccc', item: 0 }, 
] 

我已经做到了这一点

db.getCollection('points').aggregate([ 
    { 
     $lookup: { 
      from: "stream", 
      localField: "guid", 
      foreignField: "guid", 
      as: "items" 
     } 
    }, 
    { 
     $project: { 
      _id: 0, 
      guid: 1, 
      items: { 
       $size: "$items" 
      } 
     } 
    } 
]); 

如果我是在MySQL查询将是

SELECT DISTINCT 
    points.guid, 
    (
     SELECT COUNT(*) 
     FROM stream 
     WHERE guid = stream.guid and stream.email like '%o%' 
    ) AS items 
FROM points 

回答

0

答案是基于评论编辑。

您可以尝试以下聚合管道。

db.getCollection("points").aggregate([ 
         {"$lookup":{"from":"stream", "localField":"guid", "foreignField":"guid", as:"items"}}, 
         {"$unwind":"$items"}, 
         {"$group":{"_id": "$guid", "guid":{"$first":"$guid"}, "emails":{"$push":"$items.email"}}}, 
         {"$project":{"guid" :1, "emails":{"$setUnion":["$emails", [{"$literal":"io"}]]}}}, 
         {"$unwind":"$emails"}, 
         {"$match":{"emails":/[io]/}}, 
         {"$group":{"_id":"$guid", "items":{"$sum":1}}}, 
         {"$project":{"_id":0, "guid":"$_id", "items":{"$add":["$items", -1]}}} 
        ]) 

样本输出:

{ "items" : 3, "guid" : "aaa" } 
{ "items" : 1, "guid" : "ccc" } 
{ "items" : 1, "guid" : "bbb" } 

注:我已经介绍了一个虚拟的电子邮件ID - 'OI',即满足匹配条件,以确保从点收集的数据不会丢失。为了补偿这个虚拟域,最后从计数中减去-1。

+0

做得好,但如果我需要这个SELECT COUNT(*) 从流 WHERE guid = stream.guid和(stream.email like'%o%'或stream.email like'%i%')谢谢 –

+0

@MauroSala:更新了我的答案。但所有的电子邮件都有“我”在“迪士尼”... – 4J41

+0

我需要做很多或像这样的查询:SELECT COUNT(*)从流WHERE guid = stream.guid和(stream.email like' %o%'或stream.title,如'%i%'),但你的回答是正确的 –