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,谢谢,伙计,这就成功了。更新了帖子的答案和其他一些发现!