0

I have two orders

Order 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"
        }
    ]
}

Order 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"
        }
    ]
}

Now i have to get aggregated information based on project. But i only need to add cash if task on pickUp is not failed.

Order A has cash collection of 400 and order B has collection of 800 order B has a pick up task which is failed. So we don't need to add cash but delivery fee should be added.

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

Now following things which i tried is

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
    }

But i am inside condition i am unable to use elematch.

Can anyone explain me how we can achieve this????

Muhammad Waqas
  • 367
  • 3
  • 13

2 Answers2

2

$elemMatch is only applicable in match stage. For any other stages you have to use ArrayOperators. You can use $in array operator.

Converting your condition to use in operator (using java code)

AggregationExpression collectionPriceCondition = ConditionalOperators.
                      when(ArrayOperators.arrayOf("tasks.status").containsValue("FAILED")).
                      then(0.0).
                      otherwiseValueOf("cash");
s7vr
  • 73,656
  • 11
  • 106
  • 127
1

Have you tried this...

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")
Ashish Bakwad
  • 791
  • 4
  • 15