Global search over many entities

I am new to Hibernate Search. I have experience with Lucene, Nutch and Solr many years back.

I am building an application with lots of entities and I need to include search features.
I want a global search feature and a specialized/advanced search feature.

The Global search is what my question is about.

So my application is build up with lots of CRUD pages. Users can list and access details for almost everything as long as it’s in the database. The users will need to search for information/entities and I want to give them the possibility to search wide meaning searching many different entities at the same time. Since I just started to look into Hibernate Search today I do not know what is possible and not.

It seems I can only search one entity at the time but I am thinking one possibility could be to search several entities in sequence and then combine the results. I will need to order every entity by score before presenting it in the UI.

I think this will be possible but there might be a better way then me inventing the wheel or maybe I need to be talked out of the whole global search thingy because it is plain stupid? I want to hear from people that knows what is possible and not.

Actually you can search across multiple indexed types:

SearchResult<Person> result = searchSession.search( Arrays.asList( 
                Manager.class, Associate.class
        ) )
        .where( f -> f.match() 
                .field( "name" )
                .matching( "james" ) )
        .fetch( 20 ); 

This will search for managers or associates, and return a combined list of hits that contains both managers and associates, sorted by score.

See this section of the documentation for details, in particular about how things work when a field is defined in one index both not another, or defined differently in two indexes.

And if you want to target every indexed type, well, just do this:

SearchResult<Object> result = searchSession.search( Object.class )
        .where( f -> f.match() 
                .field( "name" )
                .matching( "james" ) )
        .fetch( 20 ); 

Or you can even target every indexed type implementing a given interface:

SearchResult<MyInterface> result = searchSession.search( MyInterface.class )
        .where( f -> f.match() 
                .field( "name" )
                .matching( "james" ) )
        .fetch( 20 ); 

This is actually one area where Hibernate Search 6 is much easier to use compared to Hibernate Search 5, because it provides a representation of the multi-index target and a way to build predicates against this target (the f, or “predicate factory”, in the code above), automatically checking for incompatibilities (e.g. a code field that has type integer in one index and text in another).

I strongly advise against this. It’s hard to implement correctly, and close to impossible to implement with decent performance.

But as I said above, you don’t need this anyway: searching across multiple types is a built-in feature.

1 Like

Thank you.

I implemented the global search with Object

SearchResult<Object> result = searchSession.search( Object.class )
        .where( f -> f.match() 
                .fields( "x", "y", "z", "etc" ) // from different entities
                .matching( "james" ) )
        .fetch( 20 ); 

I added fields from the most important entities. It works just great and the speed is so far lightning fast.
Since Object is returned I check the results for instance in the loop an present each entity’s data. With many entities it will be many conditions but that is the price I guess. Well worth it.

1 Like