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

如何使用Java Morphia改写包含$map和$arrayToObject的MongoDB聚合查询

Morphia实现指定MongoDB聚合查询的方案

前置准备

  • 确保你的源集合对应的实体类已经完成Morphia映射,其中items字段为列表类型,列表元素包含key、value两个属性
  • 接收聚合结果的DTO类中,items字段定义为Map<String, Object>类型,用于匹配$arrayToObject的输出结构

实现代码(适配Morphia 2.x版本)

import dev.morphia.Datastore;
import dev.morphia.aggregation.AggregationPipeline;
import static dev.morphia.aggregation.Projection.projection;
import static dev.morphia.query.Expression.*;

// 假设你已经初始化好Datastore实例
Datastore datastore = ...;

// 构造第一个$project阶段:遍历items数组,提取k/v对
var projectStage1 = projection("items",
    map(
        field("items"),
        of(
            "k", variable("this.key"),
            "v", variable("this.value")
        )
    )
);

// 构造第二个$project阶段:将k/v数组转为对象
var projectStage2 = projection("items",
    arrayToObject(field("items"))
);

// 组装聚合管道并执行
AggregationPipeline<YourSourceEntity> pipeline = datastore.aggregate(YourSourceEntity.class)
    .project(projectStage1)
    .project(projectStage2);

// 遍历结果,ResultDTO是你自定义的结果接收类
pipeline.execute(ResultDTO.class).forEachRemaining(result -> {
    // 处理返回结果
    Map<String, Object> items = result.getItems();
    // ...后续业务逻辑
});

全版本兼容方案

如果觉得API构造复杂表达式容易出错,可以直接传入原生MongoDB查询语句构造阶段,写法和原生查询完全一致,适配所有Morphia版本:

import dev.morphia.Datastore;
import dev.morphia.aggregation.AggregationPipeline;
import org.bson.Document;

Datastore datastore = ...;

// 直接用原生Mongo语句构造阶段
Document stage1 = Document.parse("""
{
    "$project": {
        "items": {
            "$map": {
                "input": "$items",
                "in": {
                    "k": "$$this.key",
                    "v": "$$this.value"
                }
            }
        }
    }
}
""");

Document stage2 = Document.parse("""
{
    "$project": {
        "items": {
            "$arrayToObject": "$items"
        }
    }
}
""");

// 组装管道执行
AggregationPipeline<YourSourceEntity> pipeline = datastore.aggregate(YourSourceEntity.class)
    .stage(stage1)
    .stage(stage2);

pipeline.execute(ResultDTO.class).forEachRemaining(result -> {
    // 处理结果
});

注意事项

  • Morphia 1.x版本的包路径为org.mongodb.morphia,核心API用法基本一致,仅需调整导入包路径即可
  • 如果聚合不需要返回源实体的其他字段,可以在project阶段添加_id: 0等配置过滤不需要的字段,减少数据传输

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 04:06:07