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;
    }
Sachin
  • 4,621
  • 6
  • 25
  • 31
  • Can you add group document class and some sample doc for testing ? – s7vr Nov 16 '16 at 22:21
  • it is the same one which you answered yesterday. Somehow it is not workign for me spring http://stackoverflow.com/questions/40625566/how-to-filter-array-in-mongodb-document-using-spring – Sachin Nov 16 '16 at 22:24
  • oh okay. Can you still add the group document class ? looks like it is failing while mapping id field. – s7vr Nov 16 '16 at 22:24
  • AggregationResults 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. – s7vr Nov 16 '16 at 22:36
  • added class to post – Sachin Nov 16 '16 at 22:45

1 Answers1

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);
s7vr
  • 73,656
  • 11
  • 106
  • 127
  • 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 result = groupResults.getMappedResults(); – Sachin Nov 17 '16 at 04:20