java - Spring框架中子文档数组字段中的过滤数组

标签 java spring spring-data aggregation-framework spring-mongo

我正在尝试从 Spring 框架项目中的 MongoDB 数组中获取元素。

我已经找到了MongoDB shell的解决方案,但我不知道如何通过Spring.data.core.aggregation实现它,Spring不支持聚合运算符之一@addFields。

有人能告诉我如何替换这个@addField 或如何以其他方式实现它吗?非常感谢!!!

MongoDB 示例数据:

{
    "_id" : 15,
    "items" : [
            {
                    "columns" : [
                            {
                                    "title" : "hhh",
                                    "value" : 10
                            },
                            {
                                    "title" : "hahaha",
                                    "value" : 20
                            }
                    ]
            },
            {
                    "columns" : [
                            {
                                    "title" : "hiii",
                                    "value" : 50
                            }
                    ]
            }
    ]
}

预期结果:

{
"_id" : 15,
"items" : [
        {
                "columns" : [
                        {
                                "title" : "hahaha",
                                "value" : 20
                        }
                ]
        },
        {
                "columns" : []
        }
]

}

MongoDB Shell的解决方案:

let value = "hahaha";

db.coll.aggregate([
    {
        "$addFields": { 
            "items": { 
                "$map": { 
                    "input": "$items", 
                    "as": "item", 
                    "in": { 
                        "columns": { 
                            "$filter": { 
                                "input": "$$item.columns", 
                                "as": "elt", 
                                "cond": { "$eq": [ "$$elt.title", value ] } 
                            } 
                        }
                    }
                } 
            } 
        } 
    } 
])

MongoDB 版本:3.4.1
Spring 版本:1.4.3

最佳答案

您可以尝试以下操作,但需要使用 1.8.5 版本。

Aggregation aggregation = newAggregation(
            project("_id").and(new AggregationExpression() {
                @Override
                public DBObject toDbObject(AggregationOperationContext aggregationOperationContext) {
                    DBObject filter = new BasicDBObject("input", "$$item.columns").append("as", "elt").append("cond",
                            new BasicDBObject("$eq", Arrays.<Object>asList("$$elt.title", "hahaha")));
                    DBObject map = new BasicDBObject("input", "$items").append("as", "item").append("in", filter);
                    return new BasicDBObject("$map", map);
                }
            }).as("items")
  );

1.10.0.RC1 中添加了对部分 Mongo3.2 聚合运算符的支持。如果您同意更新到发布候选版本,您可以使用以下版本。我在 RC 中找不到 $addFields 阶段,因此保留了 $project 阶段。

Aggregation aggregation = newAggregation(
            project("_id")
                    .and(mapItemsOf("items").as("item").andApply(filter("item.columns")
                            .as("elt")
                            .by(valueOf("elt.title").equalToValue("hahaha"))
                    )).as("items")
);

静态导入:

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
import static org.springframework.data.mongodb.core.aggregation.ArrayOperators.Filter.filter;
import static org.springframework.data.mongodb.core.aggregation.ComparisonOperators.Eq.valueOf;
import static org.springframework.data.mongodb.core.aggregation.VariableOperators.mapItemsOf;

关于java - Spring框架中子文档数组字段中的过滤数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41847249/

相关文章:

java - 如何将字符串(使用 g.drawString)置于屏幕中央

java - OnActivityResult 在 fragment 内不起作用。我该如何在我的代码上解决这个问题?

java - C++/JNI - 存储对象 (jobject) 在 vector 和数组中意外更改,C++ 或 JNI 问题?

java - 如何使用以被除数和除数作为参数的递归创建 int[] 除法?

java - OpenJpa 查询缓存在空值的情况下不刷新

java - Spring Boot 同步缓存与咖啡因不起作用

具有抽象类/继承的 Spring Data Rest Repository

elasticsearch - 使用 SpringData ElasticSearch 动态索引

java - 向现有 Java 应用程序添加 Web 界面 (Spring MVC)

java - MongoDB 更新嵌套数组的元素