2014-04-13 2 views
0

У меня есть коллекция как этотGroup/подсчитывают части поля

{"foo" : "abc-123", more fields.... } 
{"foo" : "abc-456", more fields.... } 
{"foo" : "cde-000", more fields.... } 
{"foo" : "cde-555", more fields.... } 
{"foo" : "else-9991234", more fields.... } 

и хотите группы и подсчитывают первой части foo:

{ 
    "abc": 2, 
    "cde": 2, 
    "else": 1 
} 

Я думал об использовании рамок агрегации для этого, но я не уверен, как извлечь первую часть:

myColl.aggregate([ 
    $project: { firstPart: { ???? '$foo' 

ответ

1

Жаль, что вам нужно разделить это так, иначе вы могли бы использовать оператор $ substr в конвейере агрегации.

Но так как вам нужна эта функция можно использовать MapReduce:

db.collection.mapReduce() { 
    function() { 
     var parts = this.foo.split("-"); 
     emit(parts[0], 1); 
    }, 
    function(key,values){ 
     return values.length; 
    }, 
    { "out": { "inline": 1 } } 
) 

Все, что посланное к редуктору подсчитывает «значение» в массиве, ничего с только один ключом минует редуктор, но мы уже отправлено кол-во 1.

+0

Спасибо, это работает! – georg

1

Я не уверен, что это можно сделать с монго. В конце концов вам придется разделить строку и группу на первую часть.

Если бы я был вами, я бы скорее изменил вашу схему, чтобы добавить новое поле foo1, которое будет первой частью строки. Вы можете сделать это с foreach

db.collection.find().forEach(function(el){ 
    // here split your el['foo'] and update the el with new `foo1` which will have your first part 
}) 

После этого вы можете легко использовать структуру агрегации.

+0

спасибо! Как вы думаете, можно было бы использовать для этого сокращение карты вместо AF? Добавление нового поля будет сложным в моем рабочем процессе ... – georg

Смежные вопросы