0

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?

3
  • You can try the $elemMatch projection operator. Commented Feb 10, 2021 at 11:23
  • What would be the condition? And how would you use it in Spring Data? Commented Feb 10, 2021 at 11:37
  • The Criteria class has a elemMatch method to query on the array fields. And, the Query class has the Field class 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. Commented Feb 10, 2021 at 12:50

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is what I ended up doing. I created a field lastComment in the BlogPost model. Thanks

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.