2017-02-23 65 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