spring-data-mongodb icon indicating copy to clipboard operation
spring-data-mongodb copied to clipboard

Empty array don't get parsed in @Aggregation

Open ReDestroyDeR opened this issue 3 years ago • 4 comments

When writing Aggregation in MongoRepository I was checking if array was empty and then replacing it with [0]

So, here is concrete pipeline element

Schema as follows: counter element is an output of previous stage, basically an object with one field that carries NumberInt If previous stage didn't return any object, we end up with empty array

            "    {" +
            "        $project: {" +
            "            \"_id\": 1," +
            "            \"_class\": 1," +
            "            \"counter\": {" +
            "                $cond: {" +
            "                    if: {$eq: [ \"$counter\", [ ] ]}," +
            "                    then: [0]," +
            "                    else: {" +
            "                        $map: {" +
            "                            input: \"$counter\"," +
            "                            as: \"counter\"," +
            "                            in: \"$$counter.status\"" +
            "                        }" +
            "                    }" +
            "                }" +
            "            }" +
            "        }" +
            "    }"

Query fails at if: {$eq: [ \"$counter\", [ ] ]},

Error message: Invalid $project :: caused by :: Expression $eq takes exactly 2 arguments. 1 were passed in.

Meanwhile debugger says that it parsed this part of a query as: ... { "$cond" : { "if" : { "$eq" : ["$counter"]}, "then" : [0] ...

Dependency version: spring-boot-starter-data-mongodb via spring-boot-starter-parent 2.3.3.RELEASE

Thanks

ReDestroyDeR avatar Jul 18 '22 09:07 ReDestroyDeR

As a temporary fix I left only $map in the specified stage and after the $unwind I'm doing another $project as follows:

 {
        $project: {
            "_id": 1,
            "_class": 1,
            "counter": {
                $ifNull: [
                    "$counter",
                    0
                ]
            }
        }
    }

ReDestroyDeR avatar Jul 18 '22 09:07 ReDestroyDeR

If you'd like us to spend some time investigating, please take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem. We'd need more context how the aggregation is built and executed. Maybe it would even be sufficient to use a $size: 0 instead of an $eq comparison.

christophstrobl avatar Jul 19 '22 05:07 christophstrobl

Sure. Will try to provide you reproduction example as soon as this evening.

ReDestroyDeR avatar Jul 19 '22 08:07 ReDestroyDeR

Here is demo repo. It uses testcontainers, hence, you can run it immediately. https://github.com/ReDestroyDeR/MongoAggregationFail

I discovered that version bump (parent to 2.7.2) fixes the issue, but I think this can be backported, since the Issue is in the BSON Parser.

ReDestroyDeR avatar Jul 25 '22 09:07 ReDestroyDeR

Thanks for taking the time to provide the reproducer. Happy to hear that upgrading solved the issue. A back port to the 3.0.x line (as used in the sample) is unlikely because OSS Support already ended over a year ago.

christophstrobl avatar Aug 19 '22 07:08 christophstrobl