I’m having trouble utilizing the MongoDB Java driver’s helper methods to simplify a query on my collection.
Goal: the user should be able to search all bookmarks by title (string), description (string), url (string), created date (Date), and in an array of tags (string[ ]).
The aggregation pipeline in Compass spat out this code, which DOES WORK to search the elements in the tags array:
new Document("tags",
new Document("$elemMatch",
new Document("$regex", keywords).append("$options", "i")))
I'd like to do something like this, but I can't seem to figure out the proper use of syntax to get it to work:
I’ve looked at the Java documentation for elemMatch and regex, but the method’s parameters don’t seem to work for this type of query
Filters.elemMatch("tags", Filters.regex("tags", keywords, "i"));
My whole function:
public List<Bookmark> getBookmarksBySearchKeywords(String userId, String keywords) {
if (userId == null || keywords == null) return null;
List<Bson> pipeline = new ArrayList<>();
Bson matchUserId = Aggregates.match(new Document("user_id", userId));
Bson matchFields = Aggregates.match(Filters.or(
Filters.regex("title", keywords, "i"),
Filters.regex("description", keywords, "i"),
Filters.regex("url", keywords, "i"),
Filters.regex("dateCreated", keywords, "i"),
new Document("tags",
new Document("$elemMatch",
new Document("$regex", keywords)
.append("$options", "i")))
// Filters.elemMatch("tags", Filters.regex("tags", keywords, "i"))
));
Bson sortByTitle = Aggregates.sort(Sorts.ascending("title"));
pipeline.add(matchUserId);
pipeline.add(matchFields);
pipeline.add(sortByTitle);
List<Bookmark> bookmarks = bookmarksCollection.aggregate(pipeline).into(new ArrayList<>());
return bookmarks;
}
Here’s an example of a bookmark in the database. I also need to change the front-end Vue app to submit the dateCreated field as a Date, rather than a string!
Any help is greatly appreciated!