Node.js 使用MONGOOSE查询顶级子文档数组,只返回数组中最近的N个子文档
我正在寻找查询中需要的条件、字段等,或者一个异步流来查询一个在顶层有子文档数组的文档 型号:Node.js 使用MONGOOSE查询顶级子文档数组,只返回数组中最近的N个子文档,node.js,mongodb,mongoose,posts,subdocument,Node.js,Mongodb,Mongoose,Posts,Subdocument,我正在寻找查询中需要的条件、字段等,或者一个异步流来查询一个在顶层有子文档数组的文档 型号: let postSchema = new mongoose.Schema({ date : {type: Boolean, require: true}, message : {type: String, require: true} }); let Post = new mongoose.Schema({ locid: {type: String, unique: {inde
let postSchema = new mongoose.Schema({
date : {type: Boolean, require: true},
message : {type: String, require: true}
});
let Post = new mongoose.Schema({
locid: {type: String, unique: {indexed: true}, require: true},
posts : {type: [postSchema], require: false}
});
本质上,我会提供一个Locid值,如上图所示,并将其放入一个函数中,我希望函数如下所示:
Post.methods.getLastTwentyPostsForOne = function (locid) {
return new Promise(function (values, error) {
let p = new Post();
p.find({"locid" : locid}, {/*...the conditions and elements here...*/}).exec()
.then(function (found) {
//..would return the last 20 posts, or less if there are less...
}, function (err) {
//..handle errors..
})
})
};
function returnLastTwenty(posts) {
return new Promise(function (results) {
if (posts.length === 0) {
return results([]);
}
if (posts.length <= 20) {
return results(posts);
}
let length = posts.length;
var next = [];
for (i = length - 21; i < (length -1); i++) {
next.append(posts[i]);
}
if (next.length === 20) {
return results(next);
} else {
console.log('Some Error: found more than 20 posts, but parsed less');
return results(next)
}
});
}
Post.methods.getLastTwentyPostsForOne = function (locid) {
return new Promise(function (values, error) {
let p = new Post();
p.find({"locid" : locid})
.then(function (found) {
if (found.length === 1) {
returnLastTwenty(found[0].posts)
.then(function (results) {
return values(results)
})
} else {
return error("Didn't find a unique document for locid: " + locid);
}
}, function (err) {
return error(err)
})
})
};
我能想到的最基本的方法是只获取整个数组,由于mongo按时间顺序一个接一个地存储条目,所以只需解析数组并将其中包含的最后20个或更少的帖子附加到最终数组中(使用第二个基于承诺的函数)
这使得前面的方法看起来像这样:
Post.methods.getLastTwentyPostsForOne = function (locid) {
return new Promise(function (values, error) {
let p = new Post();
p.find({"locid" : locid}, {/*...the conditions and elements here...*/}).exec()
.then(function (found) {
//..would return the last 20 posts, or less if there are less...
}, function (err) {
//..handle errors..
})
})
};
function returnLastTwenty(posts) {
return new Promise(function (results) {
if (posts.length === 0) {
return results([]);
}
if (posts.length <= 20) {
return results(posts);
}
let length = posts.length;
var next = [];
for (i = length - 21; i < (length -1); i++) {
next.append(posts[i]);
}
if (next.length === 20) {
return results(next);
} else {
console.log('Some Error: found more than 20 posts, but parsed less');
return results(next)
}
});
}
Post.methods.getLastTwentyPostsForOne = function (locid) {
return new Promise(function (values, error) {
let p = new Post();
p.find({"locid" : locid})
.then(function (found) {
if (found.length === 1) {
returnLastTwenty(found[0].posts)
.then(function (results) {
return values(results)
})
} else {
return error("Didn't find a unique document for locid: " + locid);
}
}, function (err) {
return error(err)
})
})
};
索引是通过的任意数字。它可以是来自API调用的索引,等等。其中asOfIndex应该是负数,以便从数组的底部切片,从顶部切片()。对给定的时间间隔进行切片就成了一个处理asOfIndex和amount值的问题
此外,在进行一些挖掘时,发现了一种基于日期间隔查询数组中子文档的日期元素的方法,这要归功于以下文章:
及
. 对于那些可能想要这样东西的人
function getPostsBetween(recentDate, farthestDate, forLocid) {
return new Promise(function (posts, none) {
Post.aggregate(
{'$match': {'locid': forLocid}},
{'$unwind' : '$posts'},
{'$match' :
{'$and': [
{'posts.date': {'$gt': new Date(farthestDate.toISOString())}},
{'posts.date': {'$lt': new Date(recentDate.toISOString())}}
]
}
},
{"$group" : {
'_id' : '$_id',
"posts" : {'$push' : '$posts'}
}
})
.exec()
.catch(function (err) {
return none(err);
})
.then(function (found) {
if (found.length === 0 || found.length > 1) return none();
return found(found[0].posts);
})
})
}
在投影中使用$slice怎么样,像这样的@RatanKumar,谢谢,伙计,这就成功了。更新了帖子的答案和其他一些发现!在投影中使用$slice怎么样,像这样的@RatanKumar,谢谢,伙计,这就成功了。更新了帖子的答案和其他一些发现!