Spring Data MongoDB 教程

聚合框架示例5

该示例演示了在投影操作中使用从 Sp-EL 表达式派生的简单算术运算。

Spring Expression Language (简称SpEL) 是一种功能强大的表达式语言,是 Spring 提供的,该语言类似于 JSP 当中的 EL 表达式。但提供了很多额外的功能,最出色的就是函数调用和简单字符串的模板函数。他需要使用 Spring 提供的解析器来解析,但是他不依赖于 Spring,可以独立使用。在 Spring 程序当中,我们不用管解析器,由 Spring 来帮我们自动构建。我们只需要写想要表达的字符串,交给 Spring 来进行解析即可。

示例关键代码如下:

(1)输入文档实体

public class Product {
    // 产品ID
    private String id;
    // 产品名称
    private String name;
    // 净价
    private double netPrice;
    // 单位
    private int spaceUnits;
}

(2)输出文档实体

public class Document {
    private String id;
    private String name;
    private double netPrice;
    private int spaceUnits;
    private double netPricePlus1;
    private double netPriceMinus1;
    private double grossPrice;
    private double netPriceDiv2;
    private int spaceUnitsMod2;
    private double grossPriceIncludingDiscountAndCharge;
}

(3)投影操作关键代码

TypedAggregation<Product> agg = newAggregation(Product.class,
       project("name", "netPrice")
               // 加1
               .andExpression("netPrice + 1").as("netPricePlus1")
               // 减1
               .andExpression("netPrice - 1").as("netPriceMinus1")
               // 除2
               .andExpression("netPrice / 2").as("netPriceDiv2")
               // 乘 1.19
               .andExpression("netPrice * 1.19").as("grossPrice")
               // 取 2 的模
               .andExpression("spaceUnits % 2").as("spaceUnitsMod2")
               // 复杂算数表达式
               .andExpression("(netPrice * 0.8  + 1.2) * 1.19")
                   .as("grossPriceIncludingDiscountAndCharge")

);

AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
List<Document> resultList = result.getMappedResults();
for(Document doc : resultList) {
   System.out.println(JSONObject.toJSONString(doc));
}

完整示例

(1)application.properties 配置

# Log
logging.level.root=debug

# MongoDB
spring.data.mongodb.uri=mongodb://localhost:27017/test

(2)AppConfig.java 配置类

package com.hxstrive.springdata.mongodb.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
* 配置 MongoTemplate
* @author hxstrive.com 2022/12/23
*/
@Slf4j
@Configuration
public class AppConfig {

   @Bean
   public MongoTemplate mongoTemplate(MongoDatabaseFactory mongoDatabaseFactory) {
       log.info("mongoTemplate({}, {})", mongoDatabaseFactory);
       return new MongoTemplate(mongoDatabaseFactory);
   }

}

(3)输入文档实体

import lombok.Builder;
import lombok.Data;

/**
* 产品实体
* @author hxstrive.com
*/
@Data
@Builder
public class Product {
   // 产品ID
   private String id;
   // 产品名称
   private String name;
   // 净价
   private double netPrice;
   // 单位
   private int spaceUnits;
}

(4)输出文档实体

import lombok.Data;

/**
* 结果映射实体
* @author hxstrive.com
*/
@Data
public class Document {
   private String id;
   private String name;
   private double netPrice;
   private int spaceUnits;

   private double netPricePlus1;
   private double netPriceMinus1;
   private double grossPrice;
   private double netPriceDiv2;
   private int spaceUnitsMod2;
   private double grossPriceIncludingDiscountAndCharge;
}

(5)客户端代码

import com.alibaba.fastjson.JSONObject;
import com.hxstrive.springdata.mongodb.entity.demo5.Document;
import com.hxstrive.springdata.mongodb.entity.demo5.Product;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.TypedAggregation;
import java.util.List;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;
import static org.springframework.data.mongodb.core.aggregation.Aggregation.project;

/**
* 聚合框架示例5
* @author hxstrive.com
*/
@SpringBootTest
public class AggregationFrameworkDemo5 {

   @Autowired
   private MongoTemplate mongoTemplate;

   @BeforeEach
   public void init() {
       mongoTemplate.dropCollection(Product.class);

       // 准备数据
       mongoTemplate.insert(Product.builder().id("100").name("A").netPrice(100).spaceUnits(10).build());
       mongoTemplate.insert(Product.builder().id("200").name("B").netPrice(200).spaceUnits(20).build());
       mongoTemplate.insert(Product.builder().id("300").name("C").netPrice(300).spaceUnits(30).build());
       mongoTemplate.insert(Product.builder().id("400").name("D").netPrice(400).spaceUnits(40).build());
   }

   @Test
   public void contextLoads() {
       TypedAggregation<Product> agg = newAggregation(Product.class,
               project("name", "netPrice")
                       // 加1
                       .andExpression("netPrice + 1").as("netPricePlus1")
                       // 减1
                       .andExpression("netPrice - 1").as("netPriceMinus1")
                       // 除2
                       .andExpression("netPrice / 2").as("netPriceDiv2")
                       // 乘 1.19
                       .andExpression("netPrice * 1.19").as("grossPrice")
                       // 取 2 的模
                       .andExpression("spaceUnits % 2").as("spaceUnitsMod2")
                       // 复杂算数表达式
                       .andExpression("(netPrice * 0.8  + 1.2) * 1.19")
                           .as("grossPriceIncludingDiscountAndCharge")

       );

       AggregationResults<Document> result = mongoTemplate.aggregate(agg, Document.class);
       List<Document> resultList = result.getMappedResults();
       for(Document doc : resultList) {
           System.out.println(JSONObject.toJSONString(doc));
       }
       // 结果:
       // {"grossPrice":119.0,"grossPriceIncludingDiscountAndCharge":96.628,"id":"100","name":"A",
       //   "netPrice":100.0,"netPriceDiv2":50.0,"netPriceMinus1":99.0,"netPricePlus1":101.0,"spaceUnits":0,"spaceUnitsMod2":0}
       // {"grossPrice":238.0,"grossPriceIncludingDiscountAndCharge":191.82799999999997,"id":"200",
       //   "name":"B","netPrice":200.0,"netPriceDiv2":100.0,"netPriceMinus1":199.0,"netPricePlus1":201.0,"spaceUnits":0,"spaceUnitsMod2":0}
       // {"grossPrice":357.0,"grossPriceIncludingDiscountAndCharge":287.02799999999996,"id":"300","name":"C",
       //   "netPrice":300.0,"netPriceDiv2":150.0,"netPriceMinus1":299.0,"netPricePlus1":301.0,"spaceUnits":0,"spaceUnitsMod2":0}
       // {"grossPrice":476.0,"grossPriceIncludingDiscountAndCharge":382.22799999999995,"id":"400","name":"D",
       //   "netPrice":400.0,"netPriceDiv2":200.0,"netPriceMinus1":399.0,"netPricePlus1":401.0,"spaceUnits":0,"spaceUnitsMod2":0}

       // 执行的语句如下:
       // [{ "$project" : { "name" : 1, "netPrice" : 1,
       //    "netPricePlus1" : { "$add" : ["$netPrice", 1]},
       //    "netPriceMinus1" : { "$subtract" : ["$netPrice", 1]},
       //    "netPriceDiv2" : { "$divide" : ["$netPrice", 2]},
       //    "grossPrice" : { "$multiply" : ["$netPrice", 1.19]},
       //    "spaceUnitsMod2" : { "$mod" : ["$spaceUnits", 2]},
       //    "grossPriceIncludingDiscountAndCharge" : {
       //        "$multiply" : [{ "$add" : [{ "$multiply" : ["$netPrice", 0.8]}, 1.2]}, 1.19]}
       // }}]
   }

}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号