jjrz
jjrz

Reputation: 369

MongoDB $addField and $indexOfArray in Spring Data

I am trying to implement a custom sort with MongoDB and Spring Data according to Asya Kamsky's post:

List<AggregationOperation> operations = new ArrayList<>();

operations.add(Aggregation.addFields().addField("scorrrz")
        .withValueOfExpression("{ \"$indexOfArray\" : [ [\"John\", \"Bill\"], \"$name\" ] }").build());

When I try to execute this, I get:

ERROR a.insurance.misc.ErrorAttributes - /api/v1/insurance/opportunity/all
org.springframework.expression.spel.SpelParseException: Expression [{ "$indexOfArray" : [ ["John", "Bill"], "$name" ] }] @29: EL1043E: Unexpected token. Expected 'rsquare(])' but was 'comma(,)'

Is this not the right syntaxt? How can this be done with Spring Data?

Upvotes: 2

Views: 3538

Answers (2)

Mike
Mike

Reputation: 31

If you want to calculate $indexOfArray using the array from the DB document itself, you need the aggregate pipeline to perform the calculation instead of the Java code.

Here is my solution

Aggregation.addFields()
    .addField("scorrrz")
    .withValueOf(MongoExpression.create(" $indexOfArray : [ [ 'John', 'Bill' ], '$name' ]"))
    .build()

This creates the following pipeline stage

{
    "$addFields": {
        "scorrrz": {
            "$indexOfArray": [
                [
                    "John",
                    "Bill"
                ],
                "$name"
            ]
        }
    }
}

Upvotes: 1

prasad_
prasad_

Reputation: 14287

Collection<String> nameList = Arrays.asList("John", "Bill");

Aggregation agg = newAggregation(
                    addFields()
                     .addField("scorrrz").withValue(arrayOf(nameList).indexOf("$name"))
                     .build()
);

The aggregation's projection is an $addFields stage with a $indexOfArray aggregation array operation. This will return a field scorrrz, and it will have index value or -1 when there is no match. This ran okay with Spring Boot v2.3.10 and MongoDB v4.2.8.

The run this aggregation pass the pipeline agg to the MongoTemplate#aggregate method.

Upvotes: 5

Related Questions