首页 > 解决方案 > Mongoose .populate() 或 .find() 哪个更快

问题描述

我想获取与用户相关的帖子。哪个更快

标签: javascriptnode.jsmongodbmongoosemongoose-populate

解决方案


这个基准代码表明这Post.find({ owner: user_id })有点快。

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const NUM_USERS = 100;
const NUM_POSTS_PER_USER = 10;

mongoose.connect('mongodb://localhost:27017/testdb', { useNewUrlParser: true });

const userSchema = Schema({
  posts: [{ type: Schema.Types.ObjectId, ref: 'Post' }]
});

const postSchema = Schema({
  owner: { type: Schema.Types.ObjectId, ref: 'User' },
  title: String,
  content: String,
});

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

const userIds = [];

async function seed() {
  await User.deleteMany({});
  await Post.deleteMany({});

  for (let i = 0; i < NUM_USERS; ++i) {
    const user = new User();
    await user.save();

    for (let i = 0; i < NUM_POSTS_PER_USER; ++i) {
      const post = new Post({
        owner: user,
        title: Array(50).fill('a').join(''),
        content: Array(1000).fill('b').join(''),
      });

      await post.save();

      user.posts.push(post);
    }

    await user.save();
    userIds.push(user._id);
  }
}

async function benchmarkPopulate() {
  console.time('populate');

  for (const id of userIds) {
    await User.findOne({ _id: id }).populate("posts");
  }

  console.timeEnd('populate');
}

async function benchmarkFind() {
  console.time('find');

  for (const user_id of userIds) {
    await Post.find({ owner: user_id });
  }

  console.timeEnd('find');
}

async function main() {
  await seed();
  await benchmarkPopulate();
  await benchmarkFind();
  await benchmarkPopulate();
  await benchmarkFind();
  await mongoose.disconnect();
}

main();

输出:

populate: 217.534ms
find: 121.905ms
populate: 169.181ms
find: 120.171ms

这并不奇怪,因为Post.find({ owner: user_id })只需要查询一个集合。

这些结果在运行中相当一致(即使您颠倒了基准测试的顺序)。

您的里程可能会有所不同,这种差异并不重要,尤其是当您通过网络查询数据库时。


推荐阅读