Hibernate.orgCommunity Documentation
To query a NoSQL database is a complex feat, especially as not all NoSQL solutions support all forms of query. One of the goals of Hibernate OGM is to deal with this complexity so that users don’t have to. However, that’s not yet all implemented and depending on your use case there might be better approaches you can take advantage of.
If you skipped to this section without reading Chapter 3, Architecture, I’d suggest to read at least Section 3.3, “How is data queried” as it will greatly help you choosing a query approach.
For Hibernate OGM we developed a brand new JP-QL parser which is already able to convert simple queries using Hibernate Search under the precondition that:
We do realize these are strong limitations, so while it might be interesting to try it out, for real usage we suggest for now to use either Hibernate Search full-text queries or the native query technology of the NoSQL storage you are using.
To provide an example of what kind of queries would work:
Example 7.1. Example of trivial Hibernate Query remapped on Hibernate Search
Query query = session
.createQuery("from Hypothesis h where h.description = :desc")
.setString("desc", "tomorrow it's going to rain");
@Entity @Indexed
public class Hypothesis {
@Id
public String getId() { return id; }
public void setId(String id) { this.id = id; }
private String id;
@Field(analyze=Analyze.NO)
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
private String description;
}
We actually did use Hibernate Search already in the previous example;
specifically the annotations @Indexed
and @Field
are Hibernate Search specific.
In this example the query was defined using a JP-QL string
and then defining parameters;
that’s useful if all you have a is a JP-QL Query, but it is limiting.
Hibernate Search remaps the properties annotated with @Field
in Lucene Documents, and manages the Lucene indexes
so that you can then perform Lucene Queries.
To be extremely short, Apache Lucene is a full-text indexing and query engine with excellent query performance. Featurewise, full-text means you can do much more than a simple equality match as we did in the previous example.
Let’s show another example, now creating a Lucene Query instead:
Example 7.2. Using Hibernate Search for fulltext matching
EntityManager entityManager = ...
//Add full-text superpowers to any EntityManager:
FullTextEntityManager ftem = Search.getFullTextEntityManager(entityManager);
//Optionally use the QueryBuilder to simplify Query definition:
QueryBuilder b = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity(Hypothesis.class)
.get();
//Create a Lucene Query:
Query lq = b.keyword().onField("description").matching("tomorrow").createQuery();
//Transform the Lucene Query in a JPA Query:
FullTextQuery ftQuery = ftem.createFullTextQuery(lq, Hypothesis.class);
//This is a requirement when using Hibernate OGM instead of ORM:
ftQuery.initializeObjectsWith(ObjectLookupMethod.SKIP,
DatabaseRetrievalMethod.FIND_BY_ID);
//List all matching Hypothesis:
List<Hypothesis> resultList = ftQuery.getResultList();
Assuming our database contains an Hypothesis
instance
having description "tomorrow we release",
the query above will not find the entity
because we disabled text analysis in the previous mapping.
If we enable text analysis (which is the default):
Example 7.3. Entity enabling text analysis
@Entity @Indexed
public class Hypothesis {
@Id
public String getId() { return id; }
public void setId(String id) { this.id = id; }
private String id;
@Field(analyze=Analyze.YES)
public String getDescription() { return description; }
public void setDescription(String description) { this.description = description; }
private String description;
}
Now the entity would match a query on "tomorrow" as we’re unlocking text similarity queries!
Text similarity can be very powerful as it can be configured for specific languages or domain specific terminology; it can deal with typos and synonyms, and above all it can return results by relevance.
Worth noting the Lucene index is a vectorial space of term occurrence statistics: so extracting tags from text, frequencies of strings and correlate this data makes it very easy to build efficient data analysis applications.
For a full explanation of all its capabilities and configuration options, see the Hibernate Search reference documentation.
While the potential of Lucene queries is very high, it’s not suited for all use cases Let’s see some of the limitations of Lucene Queries as our main query engine:
to-One
relations can be mapped fine,
and the Lucene community is making progress on other forms,
but restrictions on OneToMany
or ManyToMany
can’t be implemented today.