Imagine a collection of blog posts, each with an array of comments. The last comment of the array of comments is always the most recent.
{
subject: "This is my post",
comments: [
{"priority": "HIGH", "text": "Hello, my name is...", "createdAt": ISODate("2021-01-18T09:51:32.000Z")},
{"priority": "MEDIUM", "text": "I agree", "createdAt": ISODate("2021-01-19T09:51:32.000Z")},
{"priority": "LOW", "text": "Nice post", "createdAt": ISODate("2021-01-20T09:51:32.000Z")}
]
}
I want to create a query that says:
Give me all the blog posts whose most recent comment has priority "HIGH"
What I have tried:
Query query = new Query();
List<Criteria> criteriaList = new ArrayList<>();
// other filters added to the criteria list here
CommentPriority priorityEnum = CommentPriority.valueOf("HIGH");
criteriaList.add(Criteria.where("comments.-1.priority").is(priorityEnum);
query.addCriteria(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()])));
List<BlogPost> posts = mongoOperations.find(query, BlogPost.class);
This returns an empty array as the result even if there are blog posts in the collection whose last comment has priority HIGH
Query query = new Query();
List<Criteria> criteriaList = new ArrayList<>();
// other filters added to the criteria list here
CommentPriority priorityEnum = CommentPriority.valueOf("HIGH");
criteriaList.add(Criteria.where("comments.priority").is(priorityEnum);
query.addCriteria(new Criteria().andOperator(criteriaList.toArray(new Criteria[criteriaList.size()])));
List<BlogPost> posts = mongoOperations.find(query, BlogPost.class);
This returns all the blog posts that have at least one comment with priority = HIGH, which is not what I want
Any ideas?
Criteriaclass has aelemMatchmethod to query on the array fields. And, theQueryclass has theFieldclass which can be used for projection of the array elements. There are two aspects here - query filter on an array and projection of array elements.