Retrieving pages that contain any term should be simpler:
Set<SearchTerm> terms;
// the set is filled with SearchTerm objects that are already persisted.
TypedQuery<Page> query = em.createQuery(
"SELECT DISTINCT si.page FROM SearchIndex si WHERE si.term MEMBER OF :terms",
Page.class);
query.setParameter("terms", terms);
I am afraid that retrieving pages that contain all the terms requires building a dynamic query based on the number of search terms. For example, for two search terms:
TypedQuery<Page> query = em.createQuery(
"SELECT DISTINCT p FROM Page p, SearchIndex s1, SearchIndex s2 " +
"WHERE s1.page = p AND s1.term = :t1 AND s2.page = p AND s2.term = :t2",
Page.class);
query.setParameter("t1", t1).setParameter("t2", t2);
By the way, since ObjectDB supports indexed collections you may also consider a simpler schema, with no intermediate SearchIndex class:
@Entity
public class Page {
@Index
List<SearchTerm> terms;
}
In that case the query is simpler (and possibly faster):
TypedQuery<Page> query = em.createQuery(
"SELECT DISTINCT p FROM Page p " +
"WHERE :t1 MEMBER OF p.terms AND :t2 MEMBER OF p.terms",
Page.class);
query.setParameter("t1", t1).setParameter("t2", t2);
The following query should also be valid in ObjectDB:
TypedQuery<Page> query = em.createQuery(
"SELECT DISTINCT p FROM Page p WHERE p.terms.containsAll(:terms)",
Page.class);
query.setParameter("terms", terms);
but it is not standard JPQL and it would be less efficient since indexes cannot be used.