2013-10-04 1 views
0

у меня есть ряд документов, которые выглядят следующим образом:Count число раз строки соответствует поле в нескольких документах

{ 
    'domain': 'www.stackoverflow.com', 
    'time': 1380860676457 
} 
{ 
    'domain': 'www.google.com', 
    'time': 1380860678001 
} 
{ 
    'domain': 'www.stackoverflow.com', 
    'time': 1380860657233 
} 

Какой самый лучший способ в итоге следующий вывод?

{ 
    'domain': 'www.stackoverflow.com', 
    'count': 2 
} 

Существуют ли какие-либо соображения эффективности (другой способ хранения журналов?), Если начальная коллекция содержит, скажем, миллион или более документов?

+0

Для этого вы можете использовать функцию агрегации и иметь индекс в поле домена. –

ответ

3

Вы можете использовать агрегацию. Что-то вроде:

db.sites.aggregate([{ 
    $group: { 
    _id: '$domain', 
    count: {$sum: 1} 
    } 
}]); 

Эта группа в поле домена добавляет 1 для подсчета для каждого найденного документа. Для того, чтобы сделать его похожим на выходе вы хотите вы можете также добавить операцию проекционного к вашему агрегирования:

$project: { 
    domain: '$_id', 
    count: 1, 
    _id: 0 
} 
1

Что вам нужно, это просто группа по domain и сумма кусков. Вы можете сделать это с помощью метода сбора aggregate как это:

db.cls.aggregate(
{$group:{_id:"$domain", count: {$sum : 1}}}, 
{$project:{_id:0, domain:"$_id", count:"$count"}} 
) 

Во-первых, $group дает:

{ 
    "result" : [ 
      { 
        "_id" : "www.google.com", 
        "count" : 1 
      }, 
      { 
        "_id" : "www.stackoverflow.com", 
        "count" : 2 
      } 
    ], 
    "ok" : 1 
} 

И второй, $project дает:

{ 
    "result" : [ 
      { 
        "count" : 1, 
        "domain" : "www.google.com" 
      }, 
      { 
        "count" : 2, 
        "domain" : "www.stackoverflow.com" 
      } 
    ], 
    "ok" : 1 
} 

Или вы могли бы сделать это только методом сбора group:

db.cls.group({ 
    key: {domain:1}, 
    reduce: function(curr,result){ result.count += 1 }, 
    initial:{count:0} 
}) 

И для ускорения процесса у вас должен быть указатель на поле domain, как было упомянуто @AnujAneja.