You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Java Spring Boot执行文件中的MongoDB聚合查询并传参?

问题解答:MongoDB聚合查询文件化+Spring Boot执行及参数传递

完全可行,你可以将MongoDB聚合管道存储为JSON文件,在Spring Boot应用中读取并执行,同时也支持从Java端向查询传递参数。以下是具体实现方案和示例:

一、将聚合查询存储为JSON文件

把Mongo Shell中使用的聚合管道数组提取出来,保存为独立的JSON文件。比如你在Mongo Bash中执行的聚合查询:

db.orders.aggregate([
  { $match: { status: "completed" } },
  { $group: { _id: "$userId", totalSpent: { $sum: "$amount" } } }
])

将其中的管道数组保存为classpath:aggregations/order-stats-pipeline.json,内容如下:

[
  { "$match": { "status": "completed" } },
  { "$group": { "_id": "$userId", "totalSpent": { "$sum": "$amount" } } }
]

二、Spring Boot中读取文件并执行聚合

首先确保项目引入MongoDB依赖(pom.xml):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

然后编写服务类,读取JSON文件并执行聚合:

import com.mongodb.client.result.AggregateIterable;
import org.bson.Document;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;
import java.util.List;

@Service
public class OrderAggregationService {

    private final MongoTemplate mongoTemplate;
    private final ObjectMapper objectMapper;

    // 构造注入Spring默认配置的Bean
    public OrderAggregationService(MongoTemplate mongoTemplate, ObjectMapper objectMapper) {
        this.mongoTemplate = mongoTemplate;
        this.objectMapper = objectMapper;
    }

    public AggregateIterable<Document> getCompletedOrderStats() throws IOException {
        // 读取classpath下的聚合管道文件
        ClassPathResource resource = new ClassPathResource("aggregations/order-stats-pipeline.json");
        // 解析JSON数组为MongoDB Document列表
        List<Document> pipeline = objectMapper.readValue(
                resource.getInputStream(),
                new TypeReference<List<Document>>() {}
        );
        // 执行聚合查询
        return mongoTemplate.getCollection("orders").aggregate(pipeline);
    }
}

三、向文件中的查询传递参数

有两种常用的参数传递方式,按需选择:

方式1:占位符替换(简单场景)

修改JSON文件,用自定义占位符标记参数位置,比如aggregations/order-stats-with-params.json:

[
  { "$match": { "status": "{{status}}", "amount": { "$gte": {{minAmount}} } } },
  { "$group": { "_id": "$userId", "totalSpent": { "$sum": "$amount" } } }
]

在服务类中读取文件字符串后替换占位符:

public AggregateIterable<Document> getOrderStatsByStatus(String status, int minAmount) throws IOException {
    ClassPathResource resource = new ClassPathResource("aggregations/order-stats-with-params.json");
    // 读取文件为字符串
    String pipelineJson = new String(resource.getInputStream().readAllBytes());
    // 替换占位符(注意字符串参数要加引号)
    pipelineJson = pipelineJson.replace("{{status}}", "\"" + status + "\"")
                               .replace("{{minAmount}}", String.valueOf(minAmount));
    // 解析为管道列表并执行
    List<Document> pipeline = objectMapper.readValue(pipelineJson, new TypeReference<List<Document>>() {});
    return mongoTemplate.getCollection("orders").aggregate(pipeline);
}

方式2:MongoDB原生变量(推荐,安全无注入风险)

利用MongoDB的变量机制,在管道中使用$$varName定义变量,执行时传入参数值。修改JSON文件aggregations/order-stats-with-mongo-vars.json:

[
  { "$match": {
      "$expr": {
          "$and": [
              { "$eq": ["$status", "$$targetStatus"] },
              { "$gte": ["$amount", "$$minAmount"] }
          ]
      }
    }
  },
  { "$group": { "_id": "$userId", "totalSpent": { "$sum": "$amount" } } }
]

服务类中执行时传入变量:

public AggregateIterable<Document> getOrderStatsWithMongoVars(String targetStatus, int minAmount) throws IOException {
    ClassPathResource resource = new ClassPathResource("aggregations/order-stats-with-mongo-vars.json");
    List<Document> pipeline = objectMapper.readValue(
            resource.getInputStream(),
            new TypeReference<List<Document>>() {}
    );
    // 构造变量文档
    Document variables = new Document("targetStatus", targetStatus)
                                 .append("minAmount", minAmount);
    // 传入变量并执行聚合
    return mongoTemplate.getCollection("orders")
                        .aggregate(pipeline)
                        .with(variables);
}

注意事项

  • 确保JSON文件格式严格符合MongoDB聚合语法,操作符前缀$不能省略,键名必须用双引号。
  • 复杂场景优先选择MongoDB原生变量方式,避免字符串替换带来的注入风险。
  • JSON文件建议放在src/main/resources目录下,便于Spring Boot自动读取。

内容的提问来源于stack exchange,提问作者trytocode

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 22:55:25