Nodejs mongoose从两个不同的集合中根据时间取出前10条数据

Nodejs mongoose从两个不同的集合中根据时间取出前10条数据

在写子的站点的时候遇到这样一个问题:mongoose 从两个不同的集合中根据时间取出前10条数据,有什么办法么

3 回复

Nodejs Mongoose 从两个不同的集合中根据时间取出前10条数据

在开发过程中,我们常常需要从多个集合中获取最新的数据。例如,你可能有一个 Posts 集合和一个 Comments 集合,并希望将它们合并并按时间排序,然后取出最新的前10条记录。

解决方案

一种常见的方法是在应用层(即Node.js服务器端)查询两个集合,然后在内存中进行合并和排序。然而,这种方法可能会消耗大量内存,特别是在处理大量数据时。

另一种更高效的方法是使用聚合管道(aggregation pipeline)来实现这一点。Mongoose 提供了强大的聚合功能,允许我们在数据库层面进行操作,从而减少内存消耗和提高性能。

示例代码

假设我们有两个模型:

const mongoose = require('mongoose');
const { Schema } = mongoose;

// 定义 Posts 模型
const postSchema = new Schema({
    title: String,
    content: String,
    createdAt: { type: Date, default: Date.now }
});

const Post = mongoose.model('Post', postSchema);

// 定义 Comments 模型
const commentSchema = new Schema({
    text: String,
    createdAt: { type: Date, default: Date.now }
});

const Comment = mongoose.model('Comment', commentSchema);

现在我们需要从这两个集合中获取最新的前10条记录:

async function getLatestItems() {
    try {
        const latestItems = await Post.aggregate([
            { $sort: { createdAt: -1 } },
            { $limit: 5 }, // 获取最新的5条Post
            { $project: { _id: 1, type: 'post', createdAt: 1 } }
        ]);

        const latestComments = await Comment.aggregate([
            { $sort: { createdAt: -1 } },
            { $limit: 5 }, // 获取最新的5条评论
            { $project: { _id: 1, type: 'comment', createdAt: 1 } }
        ]);

        // 合并结果
        const combinedResults = latestItems.concat(latestComments);

        // 按时间排序
        combinedResults.sort((a, b) => b.createdAt - a.createdAt);

        return combinedResults.slice(0, 10); // 返回最新的10条记录
    } catch (error) {
        console.error(error);
        throw error;
    }
}

getLatestItems().then(results => {
    console.log(results);
}).catch(err => {
    console.error(err);
});

解释

  1. 定义模型:首先定义了 PostComment 两个模型。
  2. 聚合管道:使用 aggregate 方法对每个集合进行排序和限制,以获取最新的记录。
  3. 投影:使用 $project 阶段将结果简化为所需字段,并添加类型标识。
  4. 合并结果:将两个结果集合并在一起。
  5. 排序和取前10条:最后对合并后的结果进行排序,并返回最新的10条记录。

通过这种方式,我们可以高效地从两个不同的集合中获取最新的记录。


并发地取出 A 的前10 和 B 的前10 ,不就这样吗?

https://github.com/alsotang/eventr 来处理并发试试

要从两个不同的集合中根据时间取出前10条数据,可以使用 Mongoose 的 find 方法分别查询这两个集合,然后将结果合并并排序。以下是一个具体的示例代码来实现这一需求:

const mongoose = require('mongoose');
const Post = mongoose.model('Post', new mongoose.Schema({ title: String, createdAt: { type: Date, default: Date.now } }));
const Comment = mongoose.model('Comment', new mongoose.Schema({ content: String, createdAt: { type: Date, default: Date.now } }));

async function getTopPostsAndComments(limit) {
    const posts = await Post.find().sort({ createdAt: -1 }).limit(limit);
    const comments = await Comment.find().sort({ createdAt: -1 }).limit(limit);

    // 合并结果
    const combinedResults = posts.concat(comments).sort((a, b) => b.createdAt - a.createdAt).slice(0, limit);

    return combinedResults;
}

getTopPostsAndComments(10)
    .then(results => console.log(results))
    .catch(err => console.error(err));

解释:

  1. 定义模型:我们定义了两个模型 PostComment,它们都有 createdAt 字段,表示创建时间。
  2. 异步函数:使用 async/await 来处理异步操作。
  3. 查询数据:对每个集合分别执行 find 操作,并按 createdAt 字段降序排序,限制返回结果的数量为 limit(例如 10)。
  4. 合并结果:将查询到的结果合并到一个数组中,并再次按时间排序,最后取前 limit 条记录。

这样,你可以从两个不同的集合中获取最新的数据,并将其组合在一起。

回到顶部