0

Can some one show me the Spring representation of below query.

db.groupsDocument.aggregate(
{$unwind:"$groups"},
{$match:{"groups.students":"8b8a7464-4dff-4136-ab0f-ec2bfe1ec48e"}},
{$group:{ _id:"$_id",groups:{$push:"$groups"},createdDate:{$first:"$createdDate"},editedDate:{$first:"$editedDate"},editedBy:{$first:"$editedBy"}}})

Above query is working file.

I tried below code but it is not working. It is throwing error "No property _id found for type GroupsDocument!"

GroupOperation groupOperation=Aggregation.group("$_id").push("$groups").as("groups").first("$createdDate").as("createdDate")
                        .first("$editedDate").as("editedDate")
                        .first("$editedBy").as("editedBy");

 Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.unwind("$groups"),
                    Aggregation.match(where("_id.teacherId").is("5").and("groups.students").in("11")),
                    groupOperation);

 AggregationResults<BasicDBObject> groupResults = groupsMongoTemplate.aggregate(aggregation,
                    GroupsDocument.class, BasicDBObject.class);

My id in the document contains two fields as shown below

"_id" : { "teacherId" : "1", "Year" : "2016" }

Document structure

{
    "_id" : { "teacherId" : "1", "Year" : "2016" },
    "groups" : [ {
        "groupId" : "123",
        "groupName" : "Test1",
        "groupNameLowerCase" : "test1",
        "description" : "sample document",
        "students" : ["11", "22"]
         },
    {
        "groupId" : "234",
        "groupName" : "Test2",
        "groupNameLowerCase" : "test2",
        "description" : "sample document",
        "students" : ["11", "22"]
         },
        {
        "groupId" : "345",
        "groupName" : "Test3",
        "groupNameLowerCase" : "test3",
        "description" : "sample document",
        "students" : ["21", "32"]
         }
    ],
    "editedBy" : "sachin",
    "createdDate":"11/11/2016"
    "editedDate":" 11/14/2016"

}

CLASS:

@Document
public class GroupsDocument extends AbstractDocument {

    /**
     * document _id and shard key
     *
     * composite key: Teacherid, Year
     */
    @Id
    @Field(FieldDefinition.DOCUMENT_ID)
    private final GroupsDocumentId GroupsDocumentId;

    @Field(FieldDefinition.GROUPS)
    private final Collection<Group> groups;

    @Field(GroupsDocument.FieldDefinition.CREATED_DATE)
    private final Date createdDate;

    @Field(GroupsDocument.FieldDefinition.EDITED_DATE)
    private Date editedDate;

    @Field(GroupsDocument.FieldDefinition.EDITED_BY)
    private String editedBy;

    /**
     * empty constructor
     */
    @SuppressWarnings("unused")
    public GroupsDocument() {
        this(null, null, Collections.emptyList(), null, null);
    }


    public GroupsDocument(String teacherId, String year, Collection<Group> groups, String editedBy) {
        this(teacherId, year, groups, new Date(), editedBy);
    }

    public GroupsDocument(
            String teacherId, String year, Collection<Group> groups, Date createdDate, String editedBy) {
        this.GroupsDocumentId = new GroupsDocumentId(teacherId, year);
        this.groups = groups;
        this.createdDate = createdDate;
        this.editedDate = this.createdDate;
        this.editedBy = editedBy;
    }

    public GroupsDocumentId getGroupsDocumentId() {
        return GroupsDocumentId;
    }

    public Collection<Group> getGroups() {
        return groups;
    }

    public Date getEditedDate() {
        return editedDate;
    }

    public Date getCreatedDate() {
        return createdDate;
    }

    public void setEditedDate(Date editedDate) {
        this.editedDate = editedDate;
    }

    public String getEditedBy() {
        return editedBy;
    }

    public void setEditedBy(String editedBy) {
        this.editedBy = editedBy;
    }

Id class:

public class GroupsDocumentId extends AbstractDocument {

    @Field(GroupsDocument.FieldDefinition.teacherId)
    private final String teacherId;

    @Field(GroupsDocument.FieldDefinition.year)
    private final String year;

    /**
     * empty constructor
     */
    @SuppressWarnings("unused")
    public GroupsDocumentId() {
        this(null, null);
    }

    public GroupsDocumentId(String teacherId, String year) {
        this.teacherId = teacherId;
        this.year = year;
    }

    public String getteacherId() {
        return teacherId;
    }

    public String getyear() {
        return year;
    }
5
  • Can you add group document class and some sample doc for testing ? Commented Nov 16, 2016 at 22:21
  • it is the same one which you answered yesterday. Somehow it is not workign for me spring stackoverflow.com/questions/40625566/… Commented Nov 16, 2016 at 22:24
  • oh okay. Can you still add the group document class ? looks like it is failing while mapping id field. Commented Nov 16, 2016 at 22:24
  • AggregationResults<BasicDBObject> groupResults = mongoTemplate.aggregate(aggregation, "groupsDocument", BasicDBObject.class); the query runs fine when you dont include the groups document class in the method call. So please add the groups document class to the post. Commented Nov 16, 2016 at 22:36
  • added class to post Commented Nov 16, 2016 at 22:45

1 Answer 1

0

Change private final GroupsDocumentId GroupsDocumentId to private final GroupsDocumentId _id for spring mapping context to bind the id variable to the GroupDocumentId type in GroupsDocument class.

Alternatively, you can use this aggregate variant to bypass type checking.

 AggregationResults<BasicDBObject> groupResults = mongoTemplate.aggregate(aggregation,
            "groupsDocument, BasicDBObject.class);
Sign up to request clarification or add additional context in comments.

1 Comment

It started working after changing the name of the id property to _id. Even I can directly get a list of GroupDocument instead of BasicDBObject objects. But in result _id is coming as null. all other fields are mapped correctly but _id is not getting mapped. When I am using BasicDBObject then in mapped result I am getting teacherid and year as two separate fields. Code is like List<BasicDBObject> result = groupResults.getMappedResults();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.