0

I have below document structure.

{
    "_id" : { "teacherId" : "<teacherId>", "Year" : "<Year>" },
    "groups" : [ {
        "groupId" : "<uuid>",
        "groupName" : "<name>",
        "groupNameLowerCase" : "<name_in_lower_case>",
        "description" : "<desc>",
        "students" : ["<studentid1>", "<studentid2>", ...],
        "editedDate" : "<currentTimestamp>"
        },
        ...
    ],
    "editedDate" : "<currentTimestamp>",
    "points" : "<points>"
}

Consider that below two documents are present in DB

{
    "_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"]
         }
    ],
    "points" : "650"
}

{
    "_id" : { "teacherId" : "1", "Year" : "2015" },
    "groups" : [ {
        "groupId" : "123",
        "groupName" : "HOCKEY",
        "groupNameLowerCase" : "HOCKEY",
        "description" : "HOCKEY team",
        "students" : ["11", "22"]
         },
        {
        "groupId" : "234",
        "groupName" : "football",
        "groupNameLowerCase" : "football",
        "description" : "sample football",
        "students" : ["11", "22"]
         },
        {
        "groupId" : "345",
        "groupName" : "Test3",
        "groupNameLowerCase" : "test3",
        "description" : "sample document",
        "students" : ["21", "32"]
         }
    ],
    "points" : "650"

I want to select groups for the specified student and teacher combination. e.g. If I supply teacherid= 1 and student id =11 then query should return two documents with matching groups. I wrote below code to get the matching groups in document. But afterward I understand that elemMatch will only return first element matching. It will return two documents but with only one group in it.

Here I would like to understand the options available in Mongodb 2.4 to filter arrays in document returned by some query.

String teacherId = "1";
String studentId = "11";

Criteria documentSearchCriteria = where("_id.teacherId").is(teacherId)
                .and("groups")
                .elemMatch(where("students").in(studentId));

Criteria groupFilterCriteria = where("groups").elemMatch(where("students").in(studentBid));
BasicQuery query = new BasicQuery(documentSearchCriteria.getCriteriaObject(), groupFilterCriteria.getCriteriaObject());
List<GroupsDocument> groupsDocumentList = groupsMongoTemplate.find(query, GroupsDocument.class);

1 Answer 1

1

As you said elemMatch will retrieve only first object in an array so you have to use aggregate future to achieve your output

    MatchOperation match = Aggregation.match(Criteria.where("_id.teacherId").is("1").and("groups.students").in(11));
    UnwindOperation unwind = Aggregation.unwind("groups");
    GroupOperation group = Aggregation.group("_id").push("groups").as("groups").first("points").as("points");
    Aggregation aggregation = Aggregation.newAggregation(unwind, match, group);
    AggregationResults<BasicDBObject> groupResults = mongoTemplate.aggregate(aggregation,
                    CustomGroupsDocument.class, BasicDBObject.class);
    List<BasicDBObject> result = groupResults.getMappedResults();
Sign up to request clarification or add additional context in comments.

1 Comment

Do you have any example for it

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.