我有一份文件.

{
"errors" : [
    {
        "priority" : 3,
        "category" : "aaa"
        "other":"nothing"
    },
    {
        "priority" : 4,
        "category" : "bbb"
        "other":"nothing"
    },
    {
        "priority" : 2,
        "category" : "ccc"
        "other":"nothing"
    },
    {
        "priority" : 3,
        "category" : "ddd"
        "other":"nothing"
    },
    {
        "priority" : 2,
        "category" : "eee"
        "other":"nothing"
    }
    ],
"file_name" : "xxx.json",
"vehicle_id" : "esdf",
"day" : "2022-03-08"
}

我用js客户端执行命令.

db.wty_test.aggregate({
    $project: {
        '_id': 0, 'errors.priority': 1, 'errors.category': 1, 'file_name': 1, 'vehicle_id': 1,
    }
})

I get the result I want.enter image description here The errors is an array containing objects.

现在我需要用java客户端(springboot data mongo)覆盖这个命令.这是我的java代码.

import org.springframework.data.mongodb.core.MongoTemplate;
...
Aggregation aggregation = Aggregation.newAggregation(Aggregation.project("errors.priority", "errors.category", "file_name", "vehicle_id"));
mongoTemplate.aggregate(aggregation, "wty_test", HashMap.class).getMappedResults();

enter image description here The priority and category is not in errors.

How to use java to get the same result as js?

我试试嵌套的.但这不是我想要的.

enter image description here


enter image description here

推荐答案

下面是一种获得所需结果的方法.

Document projectn = new Document("$project", 
                        new Document("_id", 0L)
                        .append("file_name", 1L)
                        .append("vehicle_id", 1L)
                        .append("errors", 
                            new Document("$map", 
                                new Document("input", "$errors")
                                .append("in", 
                                    new Document("priority", "$$this.priority")
                                    .append("category", "$$this.category")
                                )
                            )
                        )
                    );

List<Document> pipeline = Arrays.asList(projectn);
List<Document> results = mongoOps.getCollection("collection_name")
                                 .aggregate(pipeline)
                                 .into(new ArrayList<>());

注意,这使用了MongoDB Java驱动程序API查询语法,Documentorg.bson.Document.本机查询到Java驱动程序的转换使用$map聚合数组运算符(看起来这是唯一的方法).

MongoTemplate.aggregate的代码是:

    Aggregation agg = newAggregation(
            project() 
            .and( 
                VariableOperators.Map.itemsOf("errors")
                    .as("e")
                    .andApply(ctx -> new Document("priority", "$$e.priority").append("category", "$$e.category") ))
            .as("errors")
            .andExclude("_id")
            .andInclude("file_name", "vehicle_id")
    );

    AggregationResults<Document> results = mongoOps.aggregate(agg, "collection_name", Document.class);


Alternate Method:

如果您的查询是关于projection的,那么您可以使用以下使用MongoTemplate#find方法的查询.构建和理解这一点要简单得多:

db.collection.find(
    {}, // your query filter
    { _id: 0, 'errors.category': 1, 'errors.priority': 1, file_name: 1, vehicle_id: 1 }
)

它的MongoTemplate个版本:

Query query = new Query();
query.fields()
     .include("errors.priority", "errors.category", "file_name", "vehicle_id")
     .exclude("_id");
List<Document> results = mongoOps.find(query, Document.class, "collection_name");

Javascript相关问答推荐

如何将拖放功能添加到我已自定义为图像的文件输入HTML标签中?

有Angular 的material .未应用收件箱中的价值变化

materialized - activeIndex返回-1

Phaser框架-将子对象附加到Actor

vscode扩展-webView Panel按钮不起任何作用

我开始使用/url?q=使用Cheerio

使用下表中所示的值初始化一个二维数组

无法在nextjs应用程序中通过id从mongoDB删除'

使用i18next在React中不重新加载翻译动态数据的问题

在nextjs服务器端api调用中传递认证凭证

在服务器上放置了Create Reaction App Build之后的空白页面

在grafana情节,避免冲突的情节和传说

一个实体一刀VS每个实体多刀S

如何根据查询结果重新排列日期

更改agGRID/Reaction中的单元格格式

无法使用Redux异步函数读取未定义的useEffect钩子的属性';map';

rxjs在每次迭代后更新数组的可观察值

无法在Adyen自定义卡安全字段创建中使用自定义占位符

REACT-本机错误:错误类型错误:无法读取未定义的容器的属性

JSON Web令牌(JWT)错误:RSA密钥对的签名无效