当前位置: 首页 > 知识库问答 >
问题:

使用spring mongotemplate进行条件查询

翟修永
2023-03-14

我想使用条件查询。

这是我的问题

db.projects.aggregate([
{
    "$group": {
        "_id": "$iecode",
        "treatmentArms": { "$first": "$evaluationDTOList" }
    }
},
{ "$unwind": "$treatmentArms" },
{
    "$group": {
        "_id": null,
        "Package": { 
            "$sum": { 
               "$cond": [ 
                   { "$eq": [ "$treatmentArms.mechanismOrPkg", "Package" ] }, 
                   1, 0
                ] 
            }
        },
        "Constraint-relaxing mechanisms": { 
            "$sum": { 
               "$cond": [ 
                    { 
                        "$and": [
                            { "$eq": [ "$treatmentArms.mechanismOrPkg", "Mechanism" ] },
                            { "$eq": [ "$treatmentArms.mechanismTested1", "Constraint-relaxing mechanisms" ] }
                        ]
                    }, 
                    1, 
                    0 ]
            }
        },
        "Delivery mechanisms": { 
            "$sum": { 
               "$cond": [ 
                    { 
                        "$and": [
                            { "$eq": [ "$treatmentArms.mechanismOrPkg", "Mechanism" ] },
                            { "$eq": [ "$treatmentArms.mechanismTested1", "Delivery mechanisms" ] }
                        ]
                    }, 
                    1, 
                    0 ]
            }
        },
        "Other": { 
            "$sum": { 
               "$cond": [ 
                    { 
                        "$and": [
                            { "$eq": [ "$treatmentArms.mechanismOrPkg", "Mechanism" ] },
                            { "$eq": [ "$treatmentArms.mechanismTested1", "Other" ] }
                        ]
                    }, 
                    1, 
                    0 ]
            }
        }
    }
}
])

这是我的java代码

DBObject groupByIECode = new BasicDBObject("$group",
                new BasicDBObject("_id", new BasicDBObject("iecode","$iecode")).append("treatmentArms",new BasicDBObject("$first","$evaluationDTOList")));
        System.out.println("groupByIECode: "+groupByIECode.toString());

        DBObject unwind = new BasicDBObject("$unwind","$treatmentArms");
        System.out.println("unwind: "+unwind.toString());


        DBObject finalCalculation = new BasicDBObject("$group",new BasicDBObject("_id",null))
                                    .append(
                                            "Package", new BasicDBObject(
                                                "$sum", new BasicDBObject(
                                                    "$cond", new Object[]{
                                                        new BasicDBObject(
                                                            "$eq", new Object[]{ "$treatmentArms.mechanismOrPkg", "Package"}
                                                        ),
                                                        1,
                                                        0
                                                    }
                                                )
                                            )
                                        );

        System.out.println("finalCalculation: "+finalCalculation);
        final AggregationOutput output = projects.aggregate(match,groupByIECode,unwind,finalCalculation);

它给出MongoException$DuplicateKey

共有1个答案

龚钧
2023-03-14

从文档中,使用Spring Data MongoDB支持MongoDB聚合框架的规范示例如下:

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

Aggregation agg = newAggregation(
    pipelineOP1(),
    pipelineOP2(),
    pipelineOPn()
);

AggregationResults<OutputType> results = mongoTemplate.aggregate(agg,
    "INPUT_COLLECTION_NAME", OutputType.class);
List<OutputType> mappedResult = results.getMappedResults();

注意,如果提供一个输入类作为newAggregation方法的第一个参数,MongoTemplate将从该类派生输入集合的名称。否则,如果不指定输入类,则必须显式提供输入集合的名称。如果提供了输入类和输入集合,则后者优先。

对于您的查询,请创建一个实现AggregationOperation接口的解决方案,以接受dbobject,该dbobject表示聚合管道中的单个组操作,并使用$cond运算符:

public class GroupAggregationOperation implements AggregationOperation {
    private DBObject operation;

    public GroupAggregationOperation (DBObject operation) {
        this.operation = operation;
    }

    @Override
    public DBObject toDBObject(AggregationOperationContext context) {
        return context.getMappedObject(operation);
    }
}

然后将$group操作实现为聚合管道中的DBObject,该DBObject与您拥有的DBObject相同:

DBObject operation = (DBObject) new BasicDBObject("$group", new BasicDBObject("_id", null))
    .append(
        "Package", new BasicDBObject(
            "$sum", new BasicDBObject(
                "$cond", new Object[]{
                    new BasicDBObject(
                        "$eq", new Object[]{ "$treatmentArms.mechanismOrPkg", "Package"}
                    ),
                    1,
                    0
                }
            )
        )
    );

然后可以将其用作:

import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;

GroupAggregationOperation groupOp = new GroupAggregationOperation(operation);
Aggregation agg = newAggregation(
    group("iecode").first("treatmentArms").as("treatmentArms"),
    unwind("treatmentArms"),
    groupOp 
);
AggregationResults<Entity> results = mongoTemplate.aggregate(agg, Entity.class); 
List<Entity> entities = results.getMappedResults();
 类似资料:
  • 问题内容: 我有两个表,一个表用于新闻,另一个表用于评论,我想获取其状态已设置为批准的评论数。 但是此查询的问题在于,无论是否存在与该新闻相对应的评论,为评论列获取的最小值为1。 任何帮助将是非常可贵的。 问题答案: 使用代替 请尝试以下方法:

  • 问题内容: 我在Postgres 11.3数据库中有一个带有列的表。 尝试更新嵌套数组名称中的所有对象。 如果路径是对象,则应将路径从对象更新为具有以下值的字符串: 如果不存在该路径,则该对象应保持不变。 使用查询测试设置:小提琴链接 所需结果: 我已经修改了查询并链接到小提琴中。有人可以看看是否正确吗? 问题答案: 平原应该有所作为。 db <>在这里 拨弄 (Postgres 11!) 为了同

  • 问题内容: 我有一个不时更新数据集的数据库。在这里,可能发生的是交付了数据库中已经存在的数据集。 目前,我首先要做的是 检查是否已经存在具有这些数据的数据集(使用WHERE语句中的数据)。如果没有返回任何值,则说明我正在执行INSERT。 但这对我来说似乎有点复杂。所以我的问题是:是否有某种条件式INSERT仅在不存在新数据集的情况下才添加它? 我正在使用 SmallSQL 问题答案: 您几乎可以

  • 在一个有四列的大数据框(“myfile”)中,我必须添加第五列,其中的值有条件地基于前四列。 更喜欢使用和的答案,主要是因为它在大型数据集中的速度。 我的数据框如下所示: 第五列(V5)的值基于一些条件规则: 现在我想使用函数在所有行上使用这些规则(以避免慢循环)。类似这样的事情(是的,我知道这样不行!): 结果应该是: 如何在dplyr中执行此操作?

  • 我有一个和这个问题很相似的问题。 我正在从表1中为表2中的字段3和字段4的所有匹配唯一组合选择所有数据。 我希望我的where子句类似于: 但这是Hibernate不允许的。 我已经尝试推出where子句,使其具有两个子查询,并根据结果检查field1和field2,但似乎子查询总是必须返回多列。我使用group by完成了这个操作,但是Hibernate会自动将group by中的列添加到投影列