猫鼬,承诺和循环

时间:2016-06-06 19:53:35

标签: javascript node.js mongodb mongoose

我正在尝试根据键检索不同的数据。 首先是我的架构:

    var SampleSchema = mongoose.Schema({
        name: {type: String, index: true},
        _atId: {type: mongoose.Schema.ObjectId, ref: atHandler.ArrayTypes.Schema, index: true},
        factors: [{
            key: {type: String, index: true},
            value: {type: String, index: true}
        }]
    });

对于存储的样本,将有0到多个因子。我有一个用例,我需要检索所有不同的键,并为每个键获取其不同的值。

期望的结果如下:

    {
        [
            { key: 'key1', values: [values] },
            { key: 'key2', values: [values] },
        ]
    }

在Mongoose(首选)或mongoose / nodejs的组合中执行此操作将非常有帮助。

我试过了:

  • Promise.all()
  • mongoose聚合
  • mongoose与查询的区别在于查询是一个关键

我有搜索StackOverflow并且没有遇到过类似的问题,或者那些足够接近我的问题...如果有人找到了一些,我也会很感激...

修改 这是一次失败的尝试。

        .get('/:sgv/factors', function(req, res){ // get all the factors associated with this SGV since the client cannot work with data from different SGVs
            // need to get distinct factors.key and then for each their collection of distinct values...
            var sgv = sanitize(req.params.sgv);

            log.debug('GET-samples-[%s]-factors', sgv);

            sampleHandler.Samples
                .distinct('factors.key')
                .lean(true)
                .exec()
                .then(function (factors) {
                    function getValuesForKey(key){
                        return sampleHandler.Samples
                            .distinct('factors.value', { 'factors.key': key})
                            .exec()
                            .then(function(results){
                                var p = new Promise(function(fullfill, reject){
                                    fullfill(results);
                                });
                                console.log(results);


                                return p;
                            })
                    }
                   function getValuesForKeys(keys){
                       return Promise.all(keys.map(getValuesForKey));
                   }

                    getValuesForKeys(factors)
                        .done(function(results){
                    //        console.log(results);
                            res.status(200).send({keys: keys, values:results});
                        }, function(err){
                            console.log(err);
                            res.status(400).send({err: err});
                        });

                })
                .catch(function (err) {
                    console.log('error: ' + err);
                    res.status(400).send({err: err});
                });

        })

结果如下,但也有一名工人死亡(使用集群)。没有任何堆栈跟踪或错误消息。

   ['blood','child','father','mother','tumor','433333','4444','4477hhjj','54','555','f2','m2','13','666','m1' ]
[ 'blood', 'child', 'father', 'mother', 'tumor', '433333', '4444', '4477hhjj', '54', '555', 'f2', 'm2', '13', '666', 'm1' ]
[ 'blood', 'child', 'father', 'mother', 'tumor', '433333', '4444', '4477hhjj', '54', '555', 'f2', 'm2' ]
[ 'blood', 'child', 'father', 'mother', 'tumor' ]
[ '433333', '4444', '4477hhjj', '54', '555', 'child', 'f2', 'm2' ]
[ '433333', '4444', '4477hhjj', '54', '555', 'child', 'f2', 'm2' ]
[ '433333', '4444', '4477hhjj', '54', '555', 'child', 'f2', 'm2' ]
[ '433333', '4444', '4477hhjj', '54', '555', 'child', 'f2', 'm2' ]
[ '433333', '4444', '4477hhjj', '54', '555', 'child', 'f2', 'm2', '13', '566', 'm1' ]

键是:['f1','f2','f3','f4','f5','f6','f8','joker'] 对于每个键,一些上述值有些相同。并非所有样本(架构)都具有相同数量的密钥......

我也尝试过Promise.all。我不太熟悉承诺而不是我对nodejs的熟悉,我必须承认,我还在学习。

1 个答案:

答案 0 :(得分:0)

所以这不是我想要的,所以如果其他人想出更好的答案,那就太好了。如果是这样,我会改变他们的答案......



        .get('/factors', function(req, res) { // get all the factors associated with this SGV since the client cannot work with data from different SGVs
          // need to get distinct factors.key and then for each their collection of distinct values...
          log.debug('GET-samples-factors');

          sampleHandler.Samples
            .distinct('factors')
            .lean(true)
            .exec()
            .then(function(data) {
              var d = [];
              for (var i = 0; i < data.length; i++) {
                if (!d[data[i].key]) {
                  d[data[i].key] = new Set();
                }
                d[data[i].key].add(data[i].value);
              }
              var f = [];
              for (var key in d) {
                if (d.hasOwnProperty(key)) {
                  f.push({
                    key: key,
                    values: Array.from(d[key])
                  });
                }
              }
              res.json(f);
            })
            .catch(function(err) {
              console.log('error: ' + err);
              res.status(400).send({
                err: err
              });
            });
        })
&#13;
&#13;
&#13;

从上面显示的mongo输入数据并将其折叠到下面,但请记住,我尚未对此进行全面测试,以验证所有样本中相同和不同值的各种组合......:

&#13;
&#13;
[{
  "key": "f1",
  "values": ["blood", "tumor", "m2", "13"]
}, {
  "key": "f4",
  "values": ["child"]
}, {
  "key": "f2",
  "values": ["father", "mother", "f2", "m1"]
}, {
  "key": "f3",
  "values": ["mother", "father", "child"]
}, {
  "key": "f7",
  "values": ["433333"]
}, {
  "key": "f5",
  "values": ["4444"]
}, {
  "key": "f8",
  "values": ["4477hhjj"]
}, {
  "key": "f6",
  "values": ["54"]
}, {
  "key": "joker",
  "values": ["555", "666"]
}]
&#13;
&#13;
&#13;