2015-12-14 25 views
0

我需要计算两个查询象下面这样:mongodb一次计数两个条件?

1. data[k]['success'] = common.find({'url': {"$regex": k}, 'result.titile':{'$ne':''}}).count() 
2. data[k]['fail'] = common.find({'url': {"$regex": k}, 'result.titile':''}).count() 

我认为这将是更有效的,如果MongoDB的可以工作象下面这样:

result = common.find({'url': {"$regex": k}) 
count1 = result.find({'result.titile':{'$ne':''}}) 
count2 = result.count() - count1 
//result do not have find or count method, just for example 

两个数都立足相同的搜索条件{'url': {"$regex": k},通过splited是否或不是。
有没有一些内置的方式来做这些,而不写自定义js?

回答

1

,如果在所有客户端支持它的async方法是首选之一。

您也可汇总如下:

  • $match具有的URL的文档。
  • $group_id作为null,并取$sum的所有文件。我们需要这些文件,以获得没有标题的那些文件的总和,因此只需使用$push运算符累积它们即可。
  • $unwind该文件。
  • $match那些没有标题的。
  • $group,并获得$sum
  • $project想要的结果。

示例代码:

db.t.aggregate([ 
{$match:{"url":{"$regex":k}}}, 
{$group:{"_id":null, 
     "count_of_url_matching_docs":{$sum:1}, 
     "docs":{$push:"$$ROOT"}}}, 
{$unwind:"$docs"}, 
{$match:{"docs.result.titile":{$ne:""}}}, 
{$group:{"_id":null, 
     "count_of_url_matching_docs":{$first:"$count_of_url_matching_docs"}, 
     "count_of_docs_with_titles":{$sum:1}}}, 
{$project:{"_id":0, 
      "count_of_docs_with_titles":"$count_of_docs_with_titles", 
      "count_difference":{$subtract:[ 
             "$count_of_url_matching_docs", 
             "$count_of_docs_with_titles"]}}} 
]) 

测试数据:

db.t.insert([ 
{"url":"s","result":{"titile":1}}, 
{"url":"s","result":{"titile":""}}, 
{"url":"s","result":{"titile":""}}, 
{"url":"s","result":{"titile":2}} 
]) 

测试结果:

{ "count_of_docs_with_titles" : 2, "count_difference" : 2 } 
1

使用.aggregate()与通过$cond分组有条件的关键:

common.aggregate([ 
    { "$match": { "url": { "$regex": k } } }, 
    { "$group": { 
     "_id": { 
      "$cond": { 
       "if": { "$ne": [ "$result.title", "" ] }, 
       "then": "success", 
       "else": "fail" 
      } 
     }, 
     "count": { "$sum": 1 } 
    }} 
]) 

但是它实际上是更有效的并行运行两个查询,如果你的环境支持它,比如用的NodeJS

async.parallel(
    [ 
    function(callback) { 
     common.count({ 
     "url": { "$regex": k }, 
     "result.title": { "$ne": "" } 
     }, function(err,count) { 
      callback(err,{ "success": count }); 
     }); 
    }, 
    function(callback) { 
     common.count({ 
     "url": { "$regex": k }, 
     "result.title": "" 
     }, function(err,count) { 
      callback(err,{ "fail": count }); 
     }); 
    } 
    ], 
    function(err,results) { 
    if (err) throw err; 
    console.log(results); 
    } 
) 

这是有道理的,因为每个项目没有被测试,并且每个结果可以在服务器上同时运行。