Saltar al contenido

Realice consultas de búsqueda de texto completo con Hibernate

Para usar el mapeo de términos, primero se debe completar la tabla de mapeo de términos.

Abre el archivo DatabaseInitializer.java desde el directorio src/main/java/com/sap/hana/hibernate/sample/app y encuentra el método importTermMappings.

@EventListener
@Transactional
@Order(3)
public void importTermMappings(ContextRefreshedEvent event) {
  Query query = this.em.createQuery( "delete from TermMapping" );
  query.executeUpdate();

  importTermMapping( "ADDRESS", "street", "st", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "avenue", "ave", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "boulevard", "blvd", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "circle", "cir", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "court", "ct", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "drive", "dr", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "hill", "hl", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "highway", "hwy", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "lane", "ln", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "place", "pl", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "plaza", "plz", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "road", "rd", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "stairway", "stwy", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "terrace", "ter", BigDecimal.valueOf( 1 ) );

  importTermMapping( "ADDRESS", "wy", "way", BigDecimal.valueOf( 1 ) );
  importTermMapping( "ADDRESS", "prk", "park", BigDecimal.valueOf( 1 ) );
}

Este método ya define asignaciones para las abreviaturas de las calles. Lo que aún falta es la implementación de la importTermMapping un método que realmente escribe los mapas en la base de datos.

Este método debe tomar un término y asignarlo a otro término utilizando un ID de lista de asignación de términos específicos y un peso específico.

Para mejorar aún más los resultados de la búsqueda, todas las subcadenas del primer término deben asignarse al segundo término para permitir la búsqueda mientras el usuario todavía está escribiendo. De lo contrario, no habría coincidencias hasta que el usuario haya terminado de escribir la palabra completa, por ejemplo, ‘bulevar’. Para garantizar que una cadena corta que pueda coincidir con otros términos no distorsione el resultado de la búsqueda, el peso del término respectivo se reducirá exponencialmente con la longitud del término.

private void importTermMapping(String listId, String term1, String term2, BigDecimal weight) {
  for ( int i = term1.length(); i > 1; i-- ) {
    String subTerm = term1.substring( 0, i );
    if ( subTerm.equals( term2 ) ) {
      continue;
    }

    TermMapping mapping = new TermMapping();
    mapping.setListId( listId );
    mapping.setMappingId( UUID.randomUUID().toString() );
    mapping.setTerm1( subTerm );
    mapping.setTerm2( term2 );
    mapping.setWeight( weight.multiply( BigDecimal.valueOf( Math.pow( 0.8, term1.length() - i ) ) ) );

    this.em.persist( mapping );
  }
}

Como puede ver, el método utiliza un for bucle que se repetirá a lo largo del término que se asignará. Para cada subcadena hasta la longitud 2, crea un término de mapeo de esa cadena al término de mapeo usando el ID de lista de mapeo dado, un nuevo ID de mapeo aleatorio, la subcadena y el término de mapeo, y un peso calculado multiplicando un peso dado por un factor que disminuye exponencialmente con la duración del término.

Salva el DatabaseInitializer.java expediente.

Hecho

Inicie sesión para responder la pregunta