2
votes

I'm using Spring Data MongoDB to generate an aggregated query. At one point I do this:

// 5. Rejoin the array with group.
group("email", "name", "surname", "birthday", "creationTime", "updateTime", "technology")
  .push(SCORES_FIELD).as(SCORES_FIELD));

The generated step (in the log) is this:

"$group" : { 
    "_id" : { 
        "email" : "$_id",
        "name" : "$name" ,
        "surname" : "$surname" , 
        "birthday" : "$birthday" , 
        "creationTime" : "$creationTime" , 
        "updateTime" : "$updateTime" , 
        "technology" : "$technology"
    } ,
    "scores" : { "$push" : "$scores"}
}

Which is perfectly fine, I've tested it on the Mongo shell and gives back exactly what I want.

The problem is that when I do the same with Spring Data, the email field (which is the _id field in Mongo) is mapped as null. There's probably something wrong in my mapping but I haven't been able to figure out what is it exactly. Here's the model:

@Document(collection = "user")
public class User implements UserDetails {

    private static final long serialVersionUID = 1L;
    private String name;
    private String surname;
    private LocalDate birthday;

    @Id
    @Field("_id")
    private String email;
    private Collection<? extends GrantedAuthority> authorities;
    private String password;
    private Set<Score> scores;
    private LocalDateTime creationTime;
    private LocalDateTime updateTime;
    private String technology;

    // Getters and setters, hashmap, equals and toString

}

I've done other queries and everything works out perfectly. I'm having this problem only on this one which is the only aggregation I do.

1
Something like group(fields( "name", "surname", "birthday", "creationTime", "updateTime", "technology").and("email", previousOperation())).push(SCORES_FIELD).as(SCORES_FIELD)); - s7vr
Thank you for the help but this is giving me the error: No property _id found for type User. The _id should be mapped into email so there's no _id field into the model. I get the same error if I put the "_id" field directly instead using the and operator. Also, I don't understand what previousOperation() is supposed to do... The JavaDoc says that it gives back a pointer to the previous operation but it actually always returns the "_id" String... - Aurasphere
Np. The _id can't be mapped into email because group stage returns multiple keys in _id document. previousOperation() is just a convenience method to return the _id from previous group operation. You can try changing to group("email").first("name").as("name").... and see if it helps. I would expect spring to read the Field annotation from the model and map the _id field back to email now. - s7vr
You are totally right, I didn't think of that. Thank you very much. If you care to leave an answer I will accept it. - Aurasphere

1 Answers

2
votes

Promoting my comment to answer.

The _id can't be mapped into email because group stage returns multiple keys in _id document. previousOperation() is just a convenience method to return the _id from previous group operation. You can try changing to group("email").first("name").as("name").... and see if it helps.

I would expect spring to read the Field annotation from the model and map the _id field back to email now.