mongodb的条件语句内如何使用元素匹配?

时间:2019-12-26 06:43:42

标签: mongodb kotlin spring-mongodb

我有两个订单

订单A:

{
    "_id": "5e0092e725473011f4b4da54",
    "cash": 400.0,
    "deliveryFee": 5.0,
    "paymentOnPickUp" : false,
    "project": {
        "_id": "5dd3b4737908cb0cf7b40f84",
        "name": "Default Instant Deliveries"
    },
    "tasks": [{
            "tripType": "PICKUP",
            "status": "UNASSIGNED"
        },
        {
            "tripType": "DELIVERY",
            "status": "UNASSIGNED"
        }
    ]
}

订单B:

{
    "_id": "5e0092e725473011f4b4da54",
    "cash": 250.0,
    "deliveryFee": 15.0,
    "paymentOnPickUp" : true,
    "project": {
        "_id": "5dd3b4737908cb0cf7b40f84",
        "name": "Default Instant Deliveries"
    },
    "tasks": [{
            "tripType": "PICKUP",
            "status": "FAILED"
        },
        {
            "tripType": "DELIVERY",
            "status": "UNASSIGNED"
        }
    ]
}

现在我必须根据项目获取汇总信息。但是我只需要在提货任务没有失败的情况下增加现金。

订单A的现金收款为400,订单B的现金收款为800,订单B的提货任务失败。因此,我们不需要增加现金,但应该增加送货费。

| Project                    | Cash | Delivery Fee | total Orders |
|----------------------------|------|--------------|--------------|
| Default Instant Deliveries | 400  | 20           | 2            |

现在我尝试的是

fun getProjectsSummary(): MutableList<OrderSummaryDto> {

        val collectionPriceCondition = ConditionalOperators.`when`(where("tasks")
                .elemMatch(where("status").`is`("FAILED"))).then(0.0).otherwiseValueOf("cash")


        val agg = Aggregation.newAggregation(
                Aggregation.project()
                        .and("cashCollection").applyCondition(collectionPriceCondition),
                Aggregation.group("project.id")
                        .sum("deliveryFee").`as`("totalDeliveryPrice")
                        .sum("cashCollection").`as`("totalCashCollection")
                        .first("project.name").`as`("projectName")
                        .count().`as`("totalOrders")
        )
        return mongoTemplate
                .aggregate(agg, "ordersCollection", OrderSummaryDto::class.java).mappedResults
    }

但是我处于病情状态,无法使用elematch。

任何人都可以向我解释我们如何实现这一目标吗??

2 个答案:

答案 0 :(得分:0)

您尝试过这个吗...

List<Criteria> criteriaList = new ArrayList<>();
criteriaList.add(where("tasks.status").`is`("FAILED"));
criteriaList.add(where("tasks.status").`nin`("COMPLETED"));
val collectionPriceCondition = ConditionalOperators.`when`(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()])))).then(0.0).otherwiseValueOf("cash")

答案 1 :(得分:0)

$elemMatch仅适用于match阶段。对于任何其他阶段,您都必须使用ArrayOperators。您可以使用$in数组运算符。

转换条件以在运算符中使用(使用Java代码)

AggregationExpression collectionPriceCondition = ConditionalOperators.
                      when(ArrayOperators.arrayOf("tasks.status").containsValue("FAILED")).
                      then(0.0).
                      otherwiseValueOf("cash");