2017-02-09 3 views
3

я определил модель данных, как это:Агрегация головоломки о mongoDB?

import mongoose from 'mongoose'; 

const schema = mongoose.Schema({ 
    title: {type: String, required: true}, 
    content: {type: String, required: true}, 
    language: {type: String, required: true}, 
    label: [{type: String, required: false}], 
    createTime: {type: Date, default: Date.now}, 
    updateTime: {type: Date, default: Date.now} 
}); 

const Snippet = mongoose.model('Snippet', schema, 'snippet'); 

export default Snippet; 

То, что я хочу, это то, что, когда я с помощью:

Snippet.aggregate({...}) 

И если данные:

[{ 
    title: 'a', 
    content: 'b', 
    language: 'javascript' 
},{ 
    title: 'a', 
    content: 'b', 
    language: 'javascript', 
    label: ['new', 'old'] 
}, 
{ 
    title: 'a', 
    content: 'b', 
    language: 'javascript', 
    label: ['old'] 
}] 

Тогда результат, что я требуется следующее:

{ 
    languageCount : [ 
    { 
    language : 'javascript', 
    count : 3 
    }], 
    labelCount : [ 
    { 
    label : 'new', 
    count : 1 
    }, 
    { 
    label : 'old', 
    count : 2 
    }] 
} 

Я понятия не имею, как закончить мою часть «...».

Любой, кто имеет какие-либо идеи об этом или каким-либо другим способом, может обойти его. Пожалуйста, скажите мне, спасибо большое!

+0

Какая у вас версия 'mongod'? – styvane

+0

Моя версия mongod 3.2.1. Если вы можете использовать некоторую функцию на основе новейшей версии, я в порядке с ней. –

ответ

2

Вы можете сделать это со следующим трубопроводом, если ваша версия mongod < = 3.2.

[ 
    { 
     "$unwind":"$label" 
    }, 
    { 
     "$group":{ 
     "_id":{ 
      "lang":"$language", 
      "label":"$label" 
     }, 
     "count_label_per_lang":{ 
      "$sum":1 
     } 
     } 
    }, 
    { 
     "$group":{ 
     "_id":"$_id.lang", 
     "labels":{ 
      "$push":{ 
       "label":"$_id.label", 
       "count":"$count_label_per_lang" 
      } 
     }, 
     "count":{ 
      "$sum":"$count_label_per_lang" 
     } 
     } 
    } 
] 
0

Что вы можете использовать при использовании агрегации - это сложенный индекс, содержащий метку language: label.

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

const projection = { _id: 1, labels : 1, count:1, languageCount:1 } 
    const responsePromise = Snippet.aggregate([ 
     { 
     $unwind:"$label" 
     }, 
     { 
     $group:{ 
      _id: {language: "$language", label : "$label"}, 
      languageCount:{$sum:1} 
     } 
     }, 
     { 
     $group:{ 
      _id:"$_id.language", 
      labels:{ 
       $push:{ 
       label:"$_id.label", 
       count:"$languageCount" 
       } 
      }, 
     count:{$sum:"$languageCount"} 
     } 
    }, 
    { $project : projection }]); 

    return responsePromise; 

В коде вызывающего абонента вы должны сделать что-то вроде:

responsePromise.then((data,error) => { 
    response.json({content:data}) 
}); 

Я считаю, что будет делать.

+0

не работает ... [{_id: null, labels: [[Object], [Object]], count: 0}] –

+0

Отсутствие двойных кавычек во втором id. Мой ответ был отредактирован. Пожалуйста, проверьте его сейчас. Я просто тестировал здесь, и это сработало. –

+0

[{"_id": null, "labels": [{"label": "old"}, {"label": "new"}], "count": 0}], кстати, двойные кавычки is not единственная часть, которую пропустили ... –

0

Мой последний андерс, основанный на mongoDB 3.4, благодаря @Styvane, вдохновляющий.

db.getCollection('snippet').aggregate([ 
    { 
     "$facet": { 
      "languageCount": [ 
       { 
        "$sortByCount": "$language" 
       }, 
       { 
        "$addFields": { 
         "language": "$_id" 
        } 
       }, 
       { 
        "$project": { 
         "_id": 0 
        } 
       } 
      ], 
      "labelCount": [ 
       { 
        "$unwind": "$label" 
       }, 
       { 
        "$sortByCount": "$label" 
       }, 
       { 
        "$addFields": { 
         "label": "$_id" 
        } 
       }, 
       { 
        "$project": { 
         "_id": 0 
        } 
       } 
      ] 
     } 
    } 
]) 
Смежные вопросы