mongodbkotlinspring-data-mongodbspring-data-mongodb-reactive

How to map array of objects to array of plain values in Spring Data Mongo


I have a collections of documents, which have an inner array of objects with two fields:

{
    "state" : [ 
        {
            "date" : ISODate("2022-08-06T00:56:29.615Z"),
            "value" : 1
        }, 
        {
            "date" : ISODate("2022-08-06T00:56:30.615Z"),
            "value" : 2
        }
    ]
}

I would like to create a projection like this:

{
    "$project": {
        "value": {
            "$max": {
                "$map": {
                    "input": {
                        "$filter": {
                            "input": "$state",
                            "as": "item",
                            "cond": {
                                "$gte": [
                                    "$$item.date",
                                    new Date("2022-07-05T00:00:00Z")
                                ]
                            }
                        }
                    },
                    "as": "filtered",
                    "in": "$$filtered.value"
                }
            }
        }
    }
}

So in result I will get max value of filtered items of array.

However as I see andApply supports only AggregationExpression. Is there a way to convert simple field reference as AggregationExpression?

It may be accomplished like this, but seems like the last max is redundant:

AccumulatorOperators.Max.maxOf(
    VariableOperators.Map.itemsOf(getDatesFilter(onTime)).`as`("filtered")
        .andApply(AccumulatorOperators.Max.maxOf("filtered.value"))
)

Solution

  • Seems like we can just construct all "$map" expression via Documents:

    AccumulatorOperators.Max.maxOf {
        Document("\$map",
            Document(mapOf(
                "input" to getDatesFilter(onTime).toDocument(),
                "as" to "filtered",
                "in" to "\$\$filtered.value"
            )))
    }