2017-02-23 30 views
0

與此集合:貓鼬找到最新版本爲每個類別

const formSch = new Schema({ 
    formversion: Number, 
    type: String, 
    blocks: [{...}], 
}); 

const Form = mongoose.model('form', formSch); 

我想找到每個類型的表單的最新版本。

現在,我手動處理結果從數據庫中獲取它們之後,但我想知道如果有一個更有效的方法(即MapReduce的或累計):

router.get('/', (req, res, next) => Form.find().exec() 
     .then((forms) => { 
      const formversions = forms.reduce((fv, curr, idx) => { 
       if (!fv[curr.type] || fv[curr.type].version < curr.formversion) { 
        // eslint-disable-next-line no-param-reassign 
        fv[curr.type] = { idx, version: curr.formversion }; 
       } 
       return fv; 
      }, {}); 
      const formTypes = Object.keys(formversions); 

      return formTypes.map((type) => { 
       const idx = formversions[type].idx; 
       return forms[idx]; 
      }); 
     }) 
     .then(res.json.bind(res)) 
     .catch(next)); 

主要的問題我用mapreduce找到的是如何保持跟蹤當前最大版本的全局變量,以便與當前元素進行比較。

這個元素

所以:

[ 
    { 
     "formversion": 1, 
     "type": "Expedient", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 2, 
     "type": "Expedient", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 1, 
     "type": "Repte", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 2, 
     "type": "Repte", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 3, 
     "type": "Repte", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 4, 
     "type": "Repte", 
     "blocks": [...], 
    }, 
] 

結果應該是:

[ 
    { 
     "formversion": 2, 
     "type": "Expedient", 
     "blocks": [...], 
    }, 
    { 
     "formversion": 4, 
     "type": "Repte", 
     "blocks": [...], 
    }, 
] 

回答

0

您可以通過formversion排序並挑選第一個:

Form.aggregate([ 
    {$sort:{"formversion":-1}}, 
    {$group:{"_id":"$type", "form":{$first:"$$ROOT"}}}, 
    {$project:{"_id":"$form._id", "type":"$_id", "blocks":"$form.blocks"}} 
], function (err, result) { 
    .... 
}); 
+0

但我需要第一版本爲每種類型的表單,而不是所有表單的第一個版本,我更新數據示例以對其進行檢查 – David

+0

哎喲,我的壞。我已經更新了答案。聚合是要走的路。不確定貓鼬是否將結果水合成模型壽。 –

+0

太棒了! 「$ project」是否可以包含完整的元素? (意思是'{$ project:{「form」:「$ root」}}' – David