I'm trying to implement a simple text search. I would like to allow a user to type any number of words, and check all of those words against the title of an article. A result would be returned if the title matched all of the words in the search (in any order).
Some example database queries would be something like this:
SELECT * FROM Article WHERE
lower(title) like lower(concat('%', '<term1>', '%'));
SELECT * FROM Article WHERE
lower(title) like lower(concat('%', '<term1>', '%'))
AND lower(title) like lower(concat('%', '<term2>', '%'));
SELECT * FROM Article WHERE
lower(title) like lower(concat('%', '<term1>', '%'))
AND lower(title) like lower(concat('%', '<term2>', '%'));
AND lower(title) like lower(concat('%', '<term3>', '%'));
Notice how the title
column is searched in each case, and will be compared with either 1, 2, or 3 (or more) terms.
Can I create a single JPQL query to do this?
Something like this:
@Query("SELECT a FROM Article a WHERE lower(a.title) in %:terms%")
Iterable<Article> findAllContainingTitle(String... terms)
It appears Java's varargs work, but more in a sense of specific values within a set.
UPDATE 1
Thanks to this question, and this link I learned how to do this directly in a Postgres query:
SELECT * FROM Article WHERE ~~* ALL(ARRAY['%term1%', '%term2%', '%term3%']);
The challenge now has been to try and convert this to a Spring Data JPA query.
Note: the ~~*
can also be exchanged with ILIKE
(case insensitive LIKE
statement).