0

I'm trying to map the results from an aggregate operation to a DTO. It's not mapping correctly and there is no error or log message to indicate what / where it goes wrong.

db.barProperty.aggregate([
{
$match: { domainObjectId : "044f4c4c-d481-4461-ae2f-301c78ff5c91"}
},
{
$sort: {
priority: 1,
issuedAt: -1
}
},
{
$group: {
"_id": "$field",
"value": {"$last": "$value"},
"issuedAt": {"$last": "$issuedAt"}
}
}
], { allowDiskUse: true });

output:

/* 1 */
{
    "_id" : "field1",
    "value" : "2021-04-05T12:15:00Z",
    "issuedAt" : ISODate("2021-06-14T00:10:00.000Z")
}

/* 2 */
{
    "_id" : "field2",
    "value" : "value2",
    "issuedAt" : ISODate("2021-06-14T00:10:00.000Z")
}

...

Java code:

    return reactiveMongoQueryTemplate.aggregate(Aggregation.newAggregation(BarProperty.class,
                    Aggregation.match(Criteria.where("domainObjectId").is(domainObjectId)),
                    Aggregation.sort(Direction.DESC, PRIORITY)
                            .and(Direction.ASC, ISSUED_AT),
                    Aggregation.group("field")
                            .last(VALUE).as(VALUE)
                            .last(ISSUED_AT).as(ISSUED_AT)
            ).withOptions(AggregationOptions.builder().allowDiskUse(true).build()), ProjectionProperty.class)
            // TODO why is no ProjectionProperty being returned
            .doOnNext(c -> {
                System.out.println("found projection property");
            })
            .collectList();


@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProjectionProperty {

    private String id;

    private String value;

    private OffsetDateTime issuedAt;
}

I've already tried _id; and field as a substitute for the id field.

EDIT 05/10/2021 using the OOTB reactiveMongoTemplate it is working fine. I've configured a custom one as I want a different pool to be used for this aggregate.

@Configuration class MultipleMongoConfig {

private final CustomMongoProperties customMongoProperties;

public MultipleMongoConfig(CustomMongoProperties customMongoProperties) {
    this.customMongoProperties = customMongoProperties;
}

@Bean
public MongoClient reactiveMongoQueryClient() {
    return MongoClients.create(createMongoClientSettings(customMongoProperties.getQuery()));
}

@Bean("mongoQueryTemplate")
public ReactiveMongoQueryTemplate reactiveMongoQueryTemplate() {
    return new ReactiveMongoQueryTemplate(reactiveMongoQueryClient(), customMongoProperties.getQuery().getDatabase());
}

private MongoClientSettings createMongoClientSettings(MongoProperties mongoProperties) {

    ConnectionString connectionString = new ConnectionString(mongoProperties.getUri());

    return MongoClientSettings.builder()
            .readConcern(ReadConcern.DEFAULT)
            .writeConcern(WriteConcern.MAJORITY)
            .readPreference(ReadPreference.primary())
            .applyConnectionString(connectionString)
            .build();
}

}

application.yaml

spring:
  data:
    mongodb:
      database: @application.name@
      authenticationDatabase: admin
      uri: ${MONGO_URI}
      query:
        uri: ${MONGO_QUERY_URI}
        database: ${MONGO_QUERY_DB}
      auto-index-creation: true
Bert Roex
  • 1
  • 1
  • Does your java code actually return any result If you exclude the mapping to POJO? Return the result of the aggregate in Java as a String. – JCompetence Oct 04 '21 at 08:21
  • The outputType is not optional, I've tried switching out ProjectionProperty,class with String.class but still it's not printing the doOnNext – Bert Roex Oct 04 '21 at 08:44
  • Have you tried to lower mongo logs to debug level? Is the query itself still what you'd expect when written from Java? `logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG` – Nico Van Belle Oct 05 '21 at 07:23
  • @NicoVanBelle I did already enable the DEBUG logging and the query itself does return what I expect. – Bert Roex Oct 05 '21 at 09:03

1 Answers1

0

Can you please first try to figure out if your aggregation is valid and return a document instead of trying to map to a DTO.

For now dont use doNext(). Approach it 1 step at a time to find out where exactly it fails

Flux<Document> result = reactiveMongoTemplate.aggregate(agg, BarProperty.class, Document.class);
JCompetence
  • 6,997
  • 3
  • 19
  • 26