I have an entity:
package com.gl.successPaths.user.entity;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import com.gl.successPaths.interests.model.InterestArea;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(collection = "user")
public class User {
@Transient
public static final String SEQUENCE_NAME = "users_sequence";
@Id
private long userId;
private String name;
private String email;
private String profileUrl;
private String profileImgUrl;
private String contactNumber;
private String designation;
private String band;
private long employeeId;
private String experience;
private String department;
private boolean isIsNotificationActive;
private Map<String, List<InterestArea>> interestAreas = new HashMap<>();
}
and another class InterestArea.java as
public class InterestArea {
private long interestAreaId;
private String interestAreaName;
private boolean isIsSelected;
}
and its json as:
{
"myMentees": [],
"interestAreas": {
"Activities & Interests": [
{
"interestAreaName": "Bike Riding",
"isSelected": false,
"interestAreaId": 17
},
{
"interestAreaName": "Cycling",
"isSelected": false,
"interestAreaId": 18
},
{
"interestAreaName": "Running",
"isSelected": false,
"interestAreaId": 19
},
{
"interestAreaName": "Cooking",
"isSelected": false,
"interestAreaId": 20
},
{
"interestAreaName": "Photography",
"isSelected": false,
"interestAreaId": 21
},
{
"interestAreaName": "Yoga/Meditation",
"isSelected": false,
"interestAreaId": 22
}
],
"Wellness": [
{
"interestAreaName": "Financial Planning",
"isSelected": false,
"interestAreaId": 11
},
{
"interestAreaName": "Health",
"isSelected": false,
"interestAreaId": 12
},
{
"interestAreaName": "Motivation",
"isSelected": false,
"interestAreaId": 13
},
{
"interestAreaName": "Work life balance",
"isSelected": false,
"interestAreaId": 14
}
],
"Social Impact": [
{
"interestAreaName": "Educate to Empower",
"isSelected": false,
"interestAreaId": 15
},
{
"interestAreaName": "Environment Drive",
"isSelected": false,
"interestAreaId": 16
}
],
"Career": [
{
"interestAreaName": "Technology",
"isSelected": false,
"interestAreaId": 1
},
{
"interestAreaName": "AI/ML",
"isSelected": false,
"interestAreaId": 2
},
{
"interestAreaName": "Cloud",
"isSelected": true,
"interestAreaId": 3
},
{
"interestAreaName": "AR/VR",
"isSelected": false,
"interestAreaId": 4
},
{
"interestAreaName": "Cloud Computing",
"isSelected": false,
"interestAreaId": 5
},
{
"interestAreaName": "DevOps",
"isSelected": false,
"interestAreaId": 6
},
{
"interestAreaName": "Mobile Apps",
"isSelected": false,
"interestAreaId": 7
},
{
"interestAreaName": "UI/UX",
"isSelected": false,
"interestAreaId": 8
},
{
"interestAreaName": "Data Science",
"isSelected": false,
"interestAreaId": 9
},
{
"interestAreaName": "Microservices & Platform",
"isSelected": false,
"interestAreaId": 10
}
]
},
"myMentors": [],
"userDetails": {
"profileUrl": "https://ghantee.com/wp-content/uploads/2022/10/mobile-jesus-wallpaper.jpg",
"isNotificationActive": false,
"profileImgUrl": "https://ghantee.com/wp-content/uploads/2022/10/mobile-jesus-wallpaper.jpg",
"contactNumber": "9689560753",
"name": "Rachit Kumar",
"employeeId": 2523,
"designation": "Software Engineer",
"band": "Band 1",
"department": "Engineering",
"experience": "3Y",
"userId": 6,
"email": "[email protected]"
}
}
Now I want to query data for all the Users where for each entry in Map i.e. interestAreas, interestAreaName is "Cloud" and isSelected = true;
I have been trying with query:
@Query("{'interestAreas': {$exists: true, $ne: []},'interestAreas': { $elemMatch: {'v': '$in': {'interestAreaName': ?0, isSelected: true}}}}")
List<User> findAllByUserInterestAreasName(String tags);
You may have to use aggregation.
db.collection.aggregate([
{
"$addFields": {
"interestArray": {
$objectToArray: "$interestAreas" //convert to an array of k,v pair, by adding new field
}
}
},
{
$match: {
"interestArray.v": { //query the v field
$elemMatch: {
"interestAreaName": "Cloud",
"isSelected": true
}
}
}
},
{
$project: {
"interestArray": 0 //remove the added field from output
}
}
]);
You can write this using either, Aggregation Framework Support or Aggregation Repository Methods
@Aggregation("<the entire pipeline>")
List<User> findAllByUserInterestAreasName(String tags);