Search code examples
javahibernatehibernate-search

hibernate search - get entity id in composite


I'd like to create a composite and add the entities id (the one in the database) as property. I tried to use f.id() but I can't map it to a long and it seems to be the document id in elasticsearch instead the database index anyway. Here is my code.

List<GlobalSearchResult> hits = searchSession.search(Searchable.class)
 .select(f -> f.composite(
    GlobalSearchResult::new,
    f.id(),
    f.field("searchType", String.class),
    f.field("searchName", String.class),
    f.field("searchDescription", String.class),
    f.score()
  ))
 .where(f -> f.simpleQueryString().fields(INDEXED_FIELDS).matching(q))
 .fetchHits( 20 );

Is there a smart, elegant way to get the id into GlobalSearchResult or do I have to get the entity and map it? That would be a lot of boilerplate code since I have many classes implementing Searchable.

Thank you for your help!


Solution

  • Your snippet of code returns the document ID, but by default that's the same as the entity ID, so this should work fine for you unless you have an exotic mapping.

    Assuming the ID of all targeted types is indeed a Long, you can retrieve the ID as a long simply by passing Long.class to id():

    EDIT: I didn't notice your code snippet was not compiling. Since you want more than 3 parameters, your "transforming" function (the first parameter to "composite") will receive a list as argument, and you'll need to cast the list elements before you pass them to the GlobalSearchResult constructor:

    List<GlobalSearchResult> hits = searchSession.search(Searchable.class)
     .select(f -> f.composite(
        list -> new GlobalSearchResult(
                (Long) list.get(0),
                (String) list.get(1),
                (String) list.get(2),
                (String) list.get(3),
                (Float) list.get(4)
        ),
        f.id(Long.class),
        f.field("searchType", String.class),
        f.field("searchName", String.class),
        f.field("searchDescription", String.class),
        f.score()
      ))
     .where(f -> f.simpleQueryString().fields(INDEXED_FIELDS).matching(q))
     .fetchHits( 20 );
    

    In Hibernate Search 6.2 we aim to provide an easier solution based on Java records and annotations, but that's still work in progress; the current implementation only works for field projections, and ID/score projections will come later (HSEARCH-4574).