javamongodbspring-bootaggregationmongotemplate

How do I ascribe the correct priority to new objects in Spring Boot?


I have the following class in my Spring Boot application:

@Document(collection = "setting")
public class Setting {
    private @MongoId(FieldType.OBJECT_ID)
    ObjectId id;
    private String name;
    private String type;
    private Integer priority;
}

I have a REST POST endpoint where I get a Setting object sent with name and type, but no priority, then I have to put it into my MongoDB. But I have to put it into the MongoDB with the correct priority.

So number 1 is highest priority, and priories are unique for each type, so can't have 2 settings with same priority within the same type. New settings get lowest priority, meaning if I have 3 settings prioritized from 1-3 then a new setting would get priority 4 and by extension if there are no settings then a new setting would get priority 1.

This is how I solve it right now:

Aggregation priorityAggregation = Aggregation.newAggregation(
    Aggregation.match(where("type").is(setting.getType)))
    Aggregation.group().max("priority").as("priority"),
    Aggregation.project("priority").andExclude("_id")
);

Map<String, Integer> maxPriority = mongo.aggregate(priorityAggregation, "setting", HashMap.class).getUniqueMappedResult();

if (maxPriority != null && maxPriority.containsKey("priority") && maxPriority.get("priority") != null) {
    baseConfig.setPriority(maxPriority.get("priority") + 1);
} else {
    baseConfig.setPriority(1);
}

MongoTemplate.save(setting);

This does the job, but it doesn't look very nice. Are there any better way of doing this?


Solution

  • You can use a query rather than aggregation, to get the max priority setting for a type. Try this:

    Query query = new Query().addCriteria(Criteria.where("type").is(setting.getType()))
                             .with(new Sort(Sort.Direction.DESC, "priority"))
                             .limit(1);
    Setting setting = mongoTemplate.findOne(query, Setting.class);
    if (!ObjectUtils.isEmpty(setting)) {
        baseConfig.setPriority(setting.getPriority() + 1);
    } else {
        baseConfig.setPriority(1);
    }