我有一个非常艰难的时间遇到一个我认为很容易的问题。我没有找到任何答案。我在Mongoose 4.5.4和MongoDb 2.2.2
我有一个看起来像这样的数据库(为了简单起见):
[
{
_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等)。我尽量避免多次打电话,并尽可能学会干净使用猫鼬。
我试过这个:
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 :(得分:0)
这是答案。我不太确定,因为我只是在学习MongoDb和Mongoose。所以,如果你认为你可以改进答案,那就不要犹豫了。
基本上,我完全不在路上。我很想念$ unwind。另外,聚合不是获得我预期的正确方法。我想拥有最后一个'与该成员匹配的每个类别的项目。但目前还没有办法限制查询的答案只有最后一次。所以最后我决定对7个类别使用promises和chaine 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 Library。我选择了默认的ES6。为此,您必须添加一行调用Mongoose:
// 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!!!');
}
});
我希望它可以帮助别人。欢呼声。
答案 1 :(得分: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');
}
});
}
});
});
}