Following in my Mongo query
{$project:{
id:"$_id",
login:"$login",
firstName: "$firstName",
lastName:"$lastName",
email:"$email",
deactivateFlag:"$deactivateFlag",
lastActivity:"$lastActivity",
company :"$organization.name",
RoleName :"$organization.roles.roleName",
isMatchingRoles: { $eq: [ "$organization.roles.orgRoleId","$userOrgMap.roleId" ] }
}
},
{ $match: {isMatchingRoles:true},
This works perfectly fine. Particularly the last $match works perfectly to reduce the duplicates. But when I tried to convert the above code to Spring data equivalent, I am facing the following problem.
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0 at java.util.ArrayList.rangeCheck(ArrayList.java:653) at java.util.ArrayList.get(ArrayList.java:429) at java.util.Collections$UnmodifiableList.get(Collections.java:1309)
Following is my Spring Data code. I printed the raw output and happen to get boolean value for isMatchingRoles which is part of my bean class which is mapped during aggregation. But when the Boolean values is getting mapped using getMappedResult , I am getting this issue.
aggregation = newAggregation(
match(getUsersCriteria(searchTxt)),
unwind("userOrgMap"),
lookup("organizations", "userOrgMap.orgId", "_id", "organization"),
unwind("organization"),
unwind("organization.roles"),
project("userId", "login", "firstName", "lastName", "email", "deactivateFlag", "lastActivity")
.and("organization.name").as("companyName")
.and("organization.roles.roleName").as("roleName")
.and(when(where("organization.roles.orgRoleId").is("userOrgMap.roleId")).then(true).otherwise(false)).as("isMatchingRoles"),
match(Criteria.where("isMatchingRoles").is(true))
AggregationResults<UserDTO> groupResults groupResults = mongoOperation.aggregate(aggregation, UserDTO.class, UserDTO.class);
System.out.println(" Raw result "+groupResults.getMappedResults().get(0));
// The above result is getting data properly for isMatchingRoles
List<UserDTO> result = groupResults.getMappedResults();
// I am getting the exception in the above code
System.out.println(" actual mapped Reesult "+result.size());
Following is my input class
@Document(collection = "users")
public class UserDTO {
@Id
private String userId;
private String login;
private String firstName;
private String lastName;
private String lastActivity;
private String email;
private boolean deactivateFlag;
private String companyName;
private String roleName;
private boolean isMatchingRoles;
public UserDTO(String userId, String login, String firstName, String lastName, String lastActivity, String email,
boolean deactivateFlag, String companyName, String roleName, boolean isMatchingRoles) {
super();
this.userId = userId;
this.login = login;
this.firstName = firstName;
this.lastName = lastName;
this.lastActivity = lastActivity;
this.email = email;
this.deactivateFlag = deactivateFlag;
this.companyName = companyName;
this.roleName = roleName;
this.isMatchingRoles = isMatchingRoles;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastActivity() {
return lastActivity;
}
public void setLastActivity(String lastActivity) {
this.lastActivity = lastActivity;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public boolean isDeactivateFlag() {
return deactivateFlag;
}
public void setDeactivateFlag(boolean deactivateFlag) {
this.deactivateFlag = deactivateFlag;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public boolean isMatchingRoles() {
return isMatchingRoles;
}
public void setMatchingRoles(boolean isMatchingRoles) {
this.isMatchingRoles = isMatchingRoles;
}
}
Following is my sample collection
user collection
{
"_id" : "123",
"login" : "abc@abc.com",
"firstName" : "xxx",
"lastName" : "yyy",
"email" : "abc@abc.com",
"deactivateFlag" : false,
"userOrgMap" : [
{
"orgId" : "999",
"roleId" : "888"
}
]
}
Organization collection
{
"_id" : "999",
"name" : "orgName",
"roles" : [
{
"orgRoleId" : "888",
"roleName" : "Standard User"
},
{
"orgRoleId" : "777",
"roleName" : "Company Administrator"
}
]
}