wap网站建设方案 pdf,二次元WordPress,网站优化公司价格如何计算,深圳宝安网站建设学习网MongoDB聚合框架旨在对文档进行分组并将其转换为聚合结果。 聚合查询包括定义将在管道中执行的几个阶段。 如果您对有关该框架的更深入的细节感兴趣#xff0c;那么 mongodb docs是一个很好的起点。 这篇文章的重点是编写一个用于查询mongodb的Web应用程序#xff0c;以便从… MongoDB聚合框架旨在对文档进行分组并将其转换为聚合结果。 聚合查询包括定义将在管道中执行的几个阶段。 如果您对有关该框架的更深入的细节感兴趣那么 mongodb docs是一个很好的起点。 这篇文章的重点是编写一个用于查询mongodb的Web应用程序以便从数据库中获取汇总结果。 借助Spring Boot和Spring Data我们将以非常简单的方式进行操作。 实际上实现该应用程序确实非常快因为Spring Boot会处理所有必要的设置而Spring Data将帮助我们配置存储库。 可以在我的Github存储库中找到源代码。 1申请 在遍历代码之前让我们看一下我们要对应用程序执行的操作。 我们的领域是我们分布在多个仓库中的产品的集合 Document
public class Product {Idprivate final String id;private final String warehouse;private final float price;public Product(String id, String warehouse, float price) {this.id id;this.warehouse warehouse;this.price price;}public String getId() {return id;}public String getWarehouse() {return warehouse;}public float getPrice() {return price;}
} 我们的目标是收集价格范围内的所有产品并按仓库分组并收集总收入和每个分组的平均价格。 在此示例中我们的仓库存储以下产品 new Product(NW1, Norwich, 3.0f);
new Product(LN1, London, 25.0f);
new Product(LN2, London, 35.0f);
new Product(LV1, Liverpool, 15.2f);
new Product(MN1, Manchester, 45.5f);
new Product(LV2, Liverpool, 23.9f);
new Product(LN3, London, 55.5f);
new Product(LD1, Leeds, 87.0f); 该应用程序将查询价格在5.0到70.0之间的产品。 所需的聚合管道步骤如下 我们将最终得到按仓库分组的汇总结果。 每个组将包含每个仓库的产品清单平均产品价格和总收入这实际上是价格的总和。 2 Maven依赖 如您所见我们有一个简短的pom.xml其中包含Spring Boot依赖项 parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion1.3.3.RELEASE/versionrelativePath/
/parentpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingjava.version1.8/java.version
/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-mongodb/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactIdscopetest/scope/dependency
/dependenciesbuildpluginsplugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactId/plugin/plugins
/build 通过将spring-boot-starter-parent定义为父pom我们设置了Spring Boot的默认设置。 主要是它设置了可能使用的一堆库的版本例如Spring或Apache Commons。 例如我们正在使用的Spring Boot 1.3.3将4.2.5.RELEASE设置为Spring框架版本。 如前几篇文章所述它没有将库添加到我们的应用程序中而只是设置版本。 定义父项后我们只需添加三个依赖项 spring-boot-starter-web主要包括Spring MVC库和嵌入式Tomcat服务器。 spring-boot-starter-test包括JUnitMockitoHamcrest和Spring Test等测试库。 spring-boot-starter-data-mongodb此依赖项包括MongoDB Java驱动程序和Spring Data Mongo库。 3应用程序设置 多亏了Spring Boot应用程序设置与依赖项设置一样简单 SpringBootApplication
public class AggregationApplication {public static void main(String[] args) {SpringApplication.run(AggregationApplication.class, args);}
} 运行main方法时我们将启动侦听8080端口的Web应用程序。 4资料库 既然我们已经正确配置了应用程序我们就可以实现存储库。 这也不难因为Spring Data负责所有布线。 Repository
public interface ProductRepository extends MongoRepositoryProduct, String {} 以下测试证明我们的应用程序已正确设置。 RunWith(SpringJUnit4ClassRunner.class)
SpringApplicationConfiguration(classes AggregationApplication.class)
WebAppConfiguration
public class AggregationApplicationTests {Autowiredprivate ProductRepository productRepository;Beforepublic void setUp() {productRepository.deleteAll();}Testpublic void contextLoads() {}Testpublic void findById() {Product product new Product(LN1, London, 5.0f);productRepository.save(product);Product foundProduct productRepository.findOne(LN1);assertNotNull(foundProduct);}
} 我们没有实现save和findOne方法。 由于我们的存储库正在扩展MongoRepository因此已经定义了它们。 5聚合查询 最后我们设置了应用程序并解释了所有步骤。 现在我们可以专注于聚合查询。 由于我们的聚合查询不是基本查询因此我们需要实现一个自定义存储库。 这些步骤是 使用我们需要的方法创建自定义存储库 public interface ProductRepositoryCustom {ListWarehouseSummary aggregate(float minPrice, float maxPrice);
} 修改第一个存储库以扩展我们的自定义存储库 Repository
public interface ProductRepository extends MongoRepositoryProduct, String, ProductRepositoryCustom {} 创建一个实现来编写聚合查询 public class ProductRepositoryImpl implements ProductRepositoryCustom {private final MongoTemplate mongoTemplate;Autowiredpublic ProductRepositoryImpl(MongoTemplate mongoTemplate) {this.mongoTemplate mongoTemplate;}Overridepublic ListWarehouseSummary aggregate(float minPrice, float maxPrice) {...}
} 现在我们将实现postgo开头所述的mongodb管道阶段。 我们的第一个操作是match操作。 我们将过滤掉超出我们价格范围的所有产品文档 private MatchOperation getMatchOperation(float minPrice, float maxPrice) {Criteria priceCriteria where(price).gt(minPrice).andOperator(where(price).lt(maxPrice));return match(priceCriteria);
} 流水线的下一个阶段是组操作。 除了按仓库对文档进行分组之外在此阶段我们还进行以下计算 last返回组中最后一个文档的仓库。 addToSet收集所有分组文档的所有唯一产品ID从而形成一个数组。 平均计算组中所有价格的平均值。 sum汇总组中的所有价格。 private GroupOperation getGroupOperation() {return group(warehouse).last(warehouse).as(warehouse).addToSet(id).as(productIds).avg(price).as(averagePrice).sum(price).as(totalRevenue);
} 管道的最后阶段是项目运营。 在这里我们指定聚合的结果字段 private ProjectionOperation getProjectOperation() {return project(productIds, averagePrice, totalRevenue).and(warehouse).previousOperation();
} 查询的构建如下 public ListWarehouseSummary aggregate(float minPrice, float maxPrice) {MatchOperation matchOperation getMatchOperation(minPrice, maxPrice);GroupOperation groupOperation getGroupOperation();ProjectionOperation projectionOperation getProjectOperation();return mongoTemplate.aggregate(Aggregation.newAggregation(matchOperation,groupOperation,projectionOperation), Product.class, WarehouseSummary.class).getMappedResults();
} 在聚合方法中我们指示输入类这是我们的产品文档。 下一个参数是输出类它是一个DTO用于存储结果聚合 public class WarehouseSummary {private String warehouse;private ListString productIds;private float averagePrice;private float totalRevenue; 我们应该通过测试来证明该结果符合我们的预期 Test
public void aggregateProducts() {saveProducts();ListWarehouseSummary warehouseSummaries productRepository.aggregate(5.0f, 70.0f);assertEquals(3, warehouseSummaries.size());WarehouseSummary liverpoolProducts getLiverpoolProducts(warehouseSummaries);assertEquals(39.1, liverpoolProducts.getTotalRevenue(), 0.01);assertEquals(19.55, liverpoolProducts.getAveragePrice(), 0.01);
}private void saveProducts() {productRepository.save(new Product(NW1, Norwich, 3.0f));productRepository.save(new Product(LN1, London, 25.0f));productRepository.save(new Product(LN2, London, 35.0f));productRepository.save(new Product(LV1, Liverpool, 15.2f));productRepository.save(new Product(MN1, Manchester, 45.5f));productRepository.save(new Product(LV2, Liverpool, 23.9f));productRepository.save(new Product(LN3, London, 55.5f));productRepository.save(new Product(LD1, Leeds, 87.0f));
}private WarehouseSummary getLiverpoolProducts(ListWarehouseSummary warehouseSummaries) {return warehouseSummaries.stream().filter(product - Liverpool.equals(product.getWarehouse())).findAny().get();
}六结论 Spring Data与MongoDB聚合框架具有良好的集成。 添加Spring Boot来配置应用程序让我们集中精力构建查询。 对于构建过程Aggregation类具有几种静态方法可帮助我们实现不同的管道阶段。 我正在Google Plus和Twitter上发布我的新帖子。 如果您要更新新内容请关注我。 翻译自: https://www.javacodegeeks.com/2016/04/data-aggregation-spring-data-mongodb-spring-boot.html