代码之家  ›  专栏  ›  技术社区  ›  Ahmad Khalafalla

Mongoose哪一个更快populate()或.find()

  •  0
  • Ahmad Khalafalla  · 技术社区  · 3 年前

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

    • 查找用户并填充帖子

      User.findOne({ _id: id}).populate("posts")

    • 或者直接在帖子模型中搜索

      Post.find({ owner: user_id })

    0 回复  |  直到 3 年前
        1
  •  4
  •   Aurast    3 年前

    此基准代码表明 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.fund({owner:user_id}) 只需要查询一个集合。

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

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