ecrb
ecrb

Reputation: 710

How to target the last item of an array in a query using Spring Data MongoDB?

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?

Upvotes: 0

Views: 726

Answers (1)

D. SM
D. SM

Reputation: 14520

Negative positions in dot notation are not a documented MongoDB feature.

Instead of looking through the array, lift the most recent comment priority out of comments up to the post - set it on the post when you are adding comments. Then you can simply query by "most recent comment priority on post = high" without the need to descend into arrays.

Upvotes: 1

Related Questions