2017-10-13 10 views
0

Je suivais document recherche mise en veille prolongée sur les facettage de: https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#query-facetingComment obtenir l'objet correspondant à hiberner recherche facette

j'ai pu générer mes facettes, par exemple, j'ai mes authorNames COUNT:

name1 = 100 
name2 = 200 
and so on.. 

Mais mon problème est de savoir comment je vais interroger l'objet Author, si je veux en afficher d'autres détails.

Aller par l'exemple que j'ai maintenant:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em); 
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get(); 

org.apache.lucene.search.Query luceneQuery = qb.all().createQuery(); 
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Book.class); 

FacetingRequest authorFacet = qb.facet().name("authorFacetRequest").onField("authors.name_facet").discrete() 
     .orderedBy(FacetSortOrder.FIELD_VALUE).includeZeroCounts(false).createFacetingRequest(); 

// retrieve facet manager and apply faceting request 
FacetManager facetManager = fullTextQuery.getFacetManager(); 
facetManager.enableFaceting(authorFacet); 

// retrieve the faceting results 
List<Facet> facets = facetManager.getFacets("authorFacetRequest"); 
facets.forEach(p -> log.info(p.getValue() + " - " + p.getCount())); 

Mais dans l'interface graphique que je veux créer un lien avec id = author.id. Mais author.id n'est pas disponible avec la facette. Donc ce que je voudrais est:

List<facetName (authorName), count, referenceId> 

Quelle est la façon la plus simple et efficace de mettre en œuvre ce? Existe-t-il un moyen de le faire sans plusieurs requêtes?

Répondre

1

Vous pouvez cibler l'identifiant de l'auteur au lieu du nom de l'auteur.

Ecrivez une classe pour tenir vos résultats:

public class EntityFacet<T> implements Facet { 
    private final Facet delegate; 
    private final T entity; 
    public EntityFacet(Facet delegate, T entity) { 
    // ... 
    } 

    // delegate all Facet methods to the delegate 

    public T getEntity() { 
    return entity; 
    } 
} 

Ajouter un champ et Facet à l'ID auteur:

@Indexed 
@Entity 
public class Author { 

    @Id 
    // Discrete faceting only works on text fields, so we don't use the default bridge 
    @Field(name = "id_for_facet", analyze = Analyze.NO, bridge = @Bridge(impl = org.hibernate.search.bridge.builtin.IntegerBridge)) 
    @Facet(name = "id_facet", forField = "id_for_facet") 
    private Integer id; 

    // ... 
} 

(Si vous avez une restriction en place dans votre @IndexedEmbedded dans le Book class, tel que includePaths, assurez-vous de les mettre à jour pour inclure cette nouvelle facette)

Si vous avez seulement besoin du nom et de l'ID, alors vous Faire deux requêtes sur les deux facettes et faire avec.

Si vous avez besoin de plus d'informations, puis changer votre code pour cibler la facette ID:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em); 
QueryBuilder qb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(Book.class).get(); 

org.apache.lucene.search.Query luceneQuery = qb.all().createQuery(); 
FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Book.class); 

FacetingRequest authorFacet = qb.facet().name("authorFacetRequest").onField("authors.id_facet").discrete() 
     .includeZeroCounts(false).createFacetingRequest(); 

// retrieve facet manager and apply faceting request 
FacetManager facetManager = fullTextQuery.getFacetManager(); 
facetManager.enableFaceting(authorFacet); 

// retrieve the faceting results 
List<Facet> facets = facetManager.getFacets("authorFacetRequest"); 

Et enfin, faire un peu de post-traitement:

List<Integer> authorIds = facets.map(f -> { 
      try { 
      return Integer.parseInt(f.getValue()); 
      } 
      catch (NumberFormatException e) { 
      throw new RuntimeException("Unexpected author ID format", e); 
      } 
     }) 
     .collect(Collectors.asList()); 
List<Author> authors = fullTextEntityManager.unwrap(Session.class) 
    .byId(Author.class) 
    .multiLoad(authorIds); 
List<EntityFacet<Author>> entityFacets = new ArrayList<>(facets.size()); 
for (int i = 0; i < facets.size()) { 
    entityFacets.add(new EntityFacet(facets.get(i), authors.get(i))); 
} 
Collator nameSort = new Collator(); 
nameSort.setStrength(Collator.PRIMARY); 
Collections.sort(entityFacets, Comparator.comparing(f -> f.getEntity().getName(), nameSort)); 
entityFacets.forEach(p -> log.info(p.getEntity() + " - " + p.getCount())); 

Je ne cherchais pas à courir le code, mais cela devrait être, donner ou prendre quelques erreurs de syntaxe.

Certes, c'est un peu trop complexe pour son propre bien, en particulier le matériel d'analyse d'identité. Mais je ne pense pas que vous puissiez faire mieux jusqu'à ce que nous ayons amélioré la facette (ce qui devrait arriver dans Search 6).