2015-07-21 2 views
0

У меня есть MongoDB с документами формы:возвращенный объект из группы MongoDB/Mongoose от

{ 
    ... 
    "template" : "templates/Template1.html", 
    ... 
} 

, где template либо "templates/Template1.html", "templates/Template2.html" или "templates/Template3.html".

Я использую этот запрос к группе template и подсчитать, сколько раз каждый template используется:

var group = { 
     key:{'template':1}, 
     reduce: function(curr, result){ result.count++ }, 
     initial: { count: 0 } 
    }; 

    messageModel.collection.group(group.key, null, group.initial, group.reduce, null, true, cb); 

я получаю обратно правильный результат, но он отформатирован так:

{ 
    "0" : { 
     "template" : "templates/Template1.html", 
     "count" : 2 }, 
    "1" : { 
     "template" : "templates/Template2.html", 
     "count" : 2 }, 
    "2" : { 
     "template" : "templates/Template3.html", 
     "count" : 1 } 
} 

мне было интересно, если это возможно изменить запрос таким образом, что он возвращает что-то вроде:

{ 
    "templates/Template1.html" : { "count" : 2 }, 
    "templates/Template2.html" : { "count" : 2 }, 
    "templates/Template3.html" : { "count" : 1 } 
} 

или даже:

{ 
    "templates/Template1.html" : 2 , 
    "templates/Template2.html" : 2 , 
    "templates/Template3.html" : 1 
} 

Я предпочел бы изменить запрос и не разобрать возвращаемый объект из исходного запроса.

+0

Чтобы быть ясным, возвращаемое значение из '.group()' и многих других операторов фактически является «массивом» объектов, а не единственным объектом, поскольку вы его представляете. Использование «данных» в качестве «ключей» также является «анти-шаблоном», которого следует избегать при использовании кода многократного использования и, в частности, обработки данных. Лучшими альтернативами очень почтенной опции '.group()' являются такие вещи, как структура агрегации. Но так же, выход предпочтительнее быть «курсором», а не единственным объектом. Поэтому пусть базы данных являются базами данных и калечат ваши собственные результаты. –

ответ

0

Как упоминалось Blakes Seven в комментариях, вы можете использовать aggregate() вместо group(), чтобы достичь почти нужного результата.

messageModel.collection.aggregate([ 
    { // Group the collection by `template` and count the occurrences 
    $group: { 
     _id: "$template", 
     count: { $sum: 1 } 
    } 
    }, 
    { // Format the output 
    $project: { 
     _id: 0, 
     template: "$_id", 
     count: 1 
    } 
    }, 
    { // Sort the formatted output 
    $sort: { template: 1 } 
    } 
]); 

Вывод будет выглядеть следующим образом:

[ 
    { 
    "template" : "templates/Template1.html", 
    "count" : 2 }, 
    { 
    "template" : "templates/Template2.html", 
    "count" : 2 }, 
    { 
    "template" : "templates/Template3.html", 
    "count" : 1 } 
    } 
] 

Опять же, как заявил Blakes в комментариях база данных может выводить только массив объектов, а не одиночного объекта. Это будет преобразование, которое вам нужно будет сделать за пределами базы данных.

Я думаю, что стоит пересмотреть, что это преобразование создает анти-шаблон и его следует избегать. Имя ключа объекта предоставляет контекст или описание для значения. Использование местоположения файла в качестве имени ключа было бы довольно неопределенным описанием, тогда как «шаблон» предоставляет немного больше информации о том, что представляет это значение.