2016-09-06 31 views
-1

我遇到了一個很困難的問題,我覺得這很容易。我沒有找到任何答案。我在貓鼬4.5.4和MongoDB 2.2.2貓鼬 - 獲得與_id匹配的每個類別的最後一個

我有一個數據庫看起來像這樣(爲簡單起見):

[ 
     { 
      _id:12547896 
      category:1, 
      state:1, 
      member:256942158, 
      laboratory:69547231, 
      dt: 8-12-2015 
     }, 
     { 
      _id:11547528 
      category:1, 
      state:3, 
      member:256942158, 
      laboratory:69547231, 
      dt: 21-12-2015 
     }, 
     { 
      _id:1554417 
      category:2, 
      state:2, 
      member:256942158, 
      laboratory:65827231, 
      dt: 18-12-2015 
     }, 
     { 
      _id:11547528 
      category:1, 
      state:3, 
      member:256942158, 
      laboratory:69547231, 
      dt:9-12-2015 
     }, 
     { 
      _id:1554417 
      category:3, 
      state:2, 
      member:256942158, 
      laboratory:65827231, 
      dt: 9-12-2015 
     } 
    ] 

我有3個類別。我想檢索一個數組,其中包含每個類別的最後一個元素(一個用於類別1,另一個用於類別2,等等),匹配'member'。如果可能的話,我儘量避免多次打電話,並學習清潔使用貓鼬。

我tryed這一點:

Collection.aggregate([ 
     { 
      $unwind:'$category' 
     }, 
     { 
      $match:{ 
       member:data.id 
      } 
     }, 
     { 
      $sort: { 
       data: -1 
      } 
     }, 
     { 
      $project: { 
       _id:0, 
       category:'$category', 
       state:'$state', 
       date:'$date' 
      } 
     }, 
     { 
      $limit: 3 
     } 
     ],function(err,ts){ 
     console.log(ts); 
    }); 

...但我沒有得到每個類別之一。我得到以下內容:

[ 
     { 
      _id:12547896 
      category:1, 
      state:1, 
      member:256942158, 
      laboratory:69547231, 
      dt: 8-12-2015 
     }, 
     { 
      _id:11547528 
      category:1, 
      state:3, 
      member:256942158, 
      laboratory:69547231, 
      dt:9-12-2015 
     }, 
     { 
      _id:1554417 
      category:3, 
      state:2, 
      member:256942158, 
      laboratory:65827231, 
      dt: 9-12-2015 
     } 
    ] 

我在做什麼錯了?我嘗試了一切,我可以在網上找到...請!

回答

0

我使用異步循環改進了查詢。它更好。 :-)

export default function loadStatus(req, err, models) { 
    // extract the mongoose model I interested about. 
    var Ts = models.ts; 
    var Mb = models.members; 
    var tot = []; 
    var data = []; 

    // prepare the function to retrieve the last update 
    function asyncLoop(i, callback) { 
     if(i < 7) { 
      // retrieve the values with the variable qr previously prepared 
      Ts.findOne({mb:req.body.id, fb:false, ds:i},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}).exec(function(err,res) { 
       // if it exists, store the values in tot 
       if(res){ 
        tot.push(res); 
       // if it doesn't exist, store a default value 
       }else{ 
        tot.push({_id:0, ds: i,st: 0,dt: 0}); 
       } 
       asyncLoop(i+1, callback); 
      }) 
     } else { 
      callback(); 
     } 
    } 

    // first retrieve the data missing of the member selected 
    return new Promise((resolve, reject) => { 
     Mb.findOne({_id:req.body.id},{date:1,docnumber:1,email:1,phone:1}).exec() 
     .then(function(member){ 
      if(member){ 
       // store the member data in a final variable 
       data.push(member); 
       // second, retrieve the las diseases correspondig to the member with an async loop 
       asyncLoop(0, function(err){ 
        data.push(tot); 
        if(data.length>0){ 
         resolve(data); 
        }else{ 
         reject('got a problem in the query chaine'); 
        } 
       }); 
      } 
     }); 
    }); 
} 
0

這是答案。我不太確定,因爲我剛剛學習MongoDb和Mongoose。所以,如果你認爲你可以改進答案,不要猶豫,寫下來。

基本上,我完全不在路上。我誤解了$放鬆。另外,聚合是不正確的方式來獲得我的預期。我想要爲每個類別匹配成員的「最後」項目。但目前還沒有辦法限制查詢的答案只有'最後'。所以最後我決定使用promises和chaine 7查詢7個類別。

這裏是架構:

var mongoose = require('mongoose'); 

var tsSchema = mongoose.Schema({ 
    ds:{ 
     type: Number, 
     required: true 
    }, 
    mb:{ 
     type: String, 
     required: true 
    }, 
    st:{ 
     type: Number, 
     required: true 
    }, 
    lb:{ 
     type: String, 
     required: true 
    }, 
    dt:{ 
     type: Date, 
     default: Date.now 
    }, 
    fb:{ 
     type: Boolean, 
     default: false 
    } 
}); 

tsSchema.index({ mb: 1, dt: -1 }); 

var Ts = module.exports = mongoose.model('ts', tsSchema); 

這裏是查詢:

export default function loadStatus(req, err, models) { 
    // extract the mongoose model I interested about. 
    var Ts = models.ts; 
    var tot = []; 
    // chaine 7 queries for the seven diseses 
    return new Promise((resolve, reject) => { 
     Ts 
     .findOne({mb:req.body.id, fb:false, ds:0},{_id:1,ds:1,st:1,dt:1}) 
     .sort({dt:-1}) 
     .exec() 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 0,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:1},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 1,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:2},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 2,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:3},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 3,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:4},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 4,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:5},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 5,st: 0,dt: 0}); 
      } 
      return Ts.findOne({mb:req.body.id, fb:false, ds:6},{_id:1,ds:1,st:1,dt:1}).sort({dt:-1}); 
     }) 
     .then(function(r){ 
      if(r){ 
       tot.push(r); 
      }else{ 
       // if null, push default value 
       tot.push({_id:0, ds: 6, fb:false, st: 0,dt: 0}); 
      } 
      if(tot.length>0){ 
       resolve(tot); 
      }else{ 
       reject('got a problem in the query chaine'); 
      } 
     }); 
    }); 
} 

重要! - >你會有這樣做的棄用警告。你必須插入一個Promise庫。我選擇了默認的ES6。要做到這一點,你必須添加一條線,你要調用貓鼬:

// connect at mongoDb datastore 
var mongoURI = "mongodb://localhost/healthprover"; 
mongoose.Promise = global.Promise; 
var db = mongoose.connect(mongoURI, function(err){ 
    if(err){ 
    console.log(err); 
    }else{ 
    console.log('Finalmente sono connesso a Mongo!!!'); 
    } 
}); 

我希望它可以幫助別人。乾杯。