1.1.34.19.2. fejezet, GraphLookup

Ez a mintakód a könyvtár szerkezet útvonallá alakítását végzi

Directory.java

@Getter
@Setter
@EqualsAndHashCode
@Document
public class Directory {
    @Id
    private String id;
    private String path;
    private Date createdAt;
    @DBRef
    private Directory parentDirectory;
}

Leképezés path string formára

    public String buildDirectoryHierarchy(Directory directory) {
        MatchOperation matchStage = Aggregation.match(Criteria.where("_id").is(directory.getId()));
 
        GraphLookupOperation graphLookupStage = Aggregation.graphLookup("directory")
                .startWith("$parentDirectory.$id")
                .connectFrom("parentDirectory.$id")
                .connectTo("_id")
                .depthField("level")
                .as("parents");
 
        Sort sortByLevelDesc = Sort.by(Sort.Direction.DESC, "level");
        SortArray sortArrayParents = SortArray.sortArray("$parents").by(sortByLevelDesc);
        AddFieldsOperation addFieldsStage = Aggregation.addFields().addField("parents").withValue(sortArrayParents).build();
 
        Cond reduceSeparatorCond = Cond.when(Eq.valueOf("$$value").equalToValue(""))
                                                            .then("")
                                                            .otherwise("/");
        Concat reduceConcatExpr = Concat.valueOf("$$value")
                                                        .concatValueOf(reduceSeparatorCond)
                                                        .concat("$$this");
        Reduce parentPathReduceExpr = Reduce.arrayOf("$parents.path")
                                                                .withInitialValue("")
                                                                .reduce(reduceConcatExpr);
 
        ExpressionVariable parentPathVar = ExpressionVariable.newVariable("parentPathCalc").forExpression(parentPathReduceExpr);
 
        ConditionalOperators.Cond finalSeparatorCond = Cond.when(Eq.valueOf("$$parentPathCalc").equalToValue(""))
                                                           .then("") // No separator if parent path is empty
                                                           .otherwise("/");
 
        StringOperators.Concat finalConcatExpr = Concat.valueOf("$$parentPathCalc")
                                                        .concatValueOf(finalSeparatorCond)
                                                        .concatValueOf("$path");
 
        Let letExpr = Let.define(parentPathVar).andApply(finalConcatExpr);
 
        ProjectionOperation projectStage = Aggregation.project()
                .andExclude("_id")
                .and(letExpr).as("fullPath");
 
 
        Aggregation aggregation = Aggregation.newAggregation(
                matchStage,
                graphLookupStage,
                addFieldsStage,
                projectStage 
        );
 
        AggregationResults<FullPathResult> results = mongoTemplate.aggregate(
                aggregation, "directory", FullPathResult.class
        );
 
        FullPathResult uniqueResult = results.getUniqueMappedResult();
 
        return Optional.ofNullable(uniqueResult)
                .map(FullPathResult::getFullPath)
                .orElse(null);
    }