Pagination 使用聚合管道的mongodb缓存

Pagination 使用聚合管道的mongodb缓存,pagination,aggregation-framework,query-optimization,spring-webflux,Pagination,Aggregation Framework,Query Optimization,Spring Webflux,mongodb聚合管道类 db.testing.aggregate( { $match : {hosting : "aws.amazon.com"} }, { $group : { _id : "$hosting", total : { $sum : 1 } } }, { $project : { title : 1 , author : 1, <few other transformations> } {$

mongodb聚合管道类

db.testing.aggregate(
    { 
    $match : {hosting : "aws.amazon.com"}
    },
    { 
    $group : { _id : "$hosting", total : { $sum : 1 } }
    },
    {
    $project : { title : 1 , author : 1, <few other transformations> }
    {$sort : {total : -1}}
);
可以使用每个页面的外部API级缓存,这将减少重复加载相同页面的时间,但由于排序导致的线性扫描,第一次加载每个页面将非常痛苦

  • 处理应用程序中的分页。
    • 缓存findAll结果,即列表findAll()
    • 现在将在服务层处理分页,并发布结果
    • 从下一个请求开始,您将引用缓存的结果,并从缓存发送所需的一组记录

  • 问题:若数据库并没有做一些神奇的优化,那个么第二种方法似乎更好。在第1部分中,我的观点是,由于管道涉及排序,因此每个页面请求都会扫描整个表,这将是次优的。你的看法是什么?应该做哪一个?你会选择什么?好的做法是什么(是否建议将一些db逻辑移动到服务层进行优化)?

    这取决于您的数据

    MongoDB不会缓存查询结果以返回相同查询的缓存结果

    但是,您可以创建(从源代码+管道)并更新它。这将允许您拥有具有良好分页性能的聚合数据,并定期更新内容。您可以创建索引以获得更好的性能(无需在服务层中开发额外的逻辑)

    此外,如果您总是通过宿主字段筛选和
    $group
    ,则在最后
    $sort
    下一个ot
    $match
    阶段进行MongoDB索引交换可能会受益。在这种情况下,MongoDB将使用索引进行筛选+排序,并在内存中完成分页

    db.testing.createIndex({hosting:-1})
    
    db.collection.aggregate([
      {
        $match: {
          hosting: "aws.amazon.com"
        }
      },
      {
        $sort: {
          hosting: -1
        }
      },
      {
        $group: {
          _id: "$hosting",
          title: {
            $first: "$title"
          },
          author: {
            $first: "$author"
          },
          total: {
            $sum: 1
          }
        }
      },
      {
        $project: {
          title: 1,
          author: 1,
          total: 1
        }
      },
      { $skip : pageNumber * pageSize },
      { $limit : pageSize }
    ])
    
    db.testing.createIndex({hosting:-1})
    
    db.collection.aggregate([
      {
        $match: {
          hosting: "aws.amazon.com"
        }
      },
      {
        $sort: {
          hosting: -1
        }
      },
      {
        $group: {
          _id: "$hosting",
          title: {
            $first: "$title"
          },
          author: {
            $first: "$author"
          },
          total: {
            $sum: 1
          }
        }
      },
      {
        $project: {
          title: 1,
          author: 1,
          total: 1
        }
      },
      { $skip : pageNumber * pageSize },
      { $limit : pageSize }
    ])