Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-11-30 22:14:01 +01:00
padre 7573449466
commit f2d33118d5
Se han modificado 3 ficheros con 93 adiciones y 74 borrados

14
pom.xml
Ver fichero

@@ -4,7 +4,7 @@
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId> <artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.1</version> <version>4.0.0</version>
<relativePath /> <!-- lookup parent from repository --> <relativePath /> <!-- lookup parent from repository -->
</parent> </parent>
<groupId>com.manalejandro</groupId> <groupId>com.manalejandro</groupId>
@@ -36,17 +36,17 @@
<dependency> <dependency>
<groupId>org.tensorflow</groupId> <groupId>org.tensorflow</groupId>
<artifactId>tensorflow-core-platform</artifactId> <artifactId>tensorflow-core-platform</artifactId>
<version>0.4.0</version> <version>1.1.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId> <artifactId>tika-core</artifactId>
<version>2.1.0</version> <version>3.2.3</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.tika</groupId> <groupId>org.apache.tika</groupId>
<artifactId>tika-parsers-standard-package</artifactId> <artifactId>tika-parsers-standard-package</artifactId>
<version>2.1.0</version> <version>3.2.3</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>xml-apis</groupId> <groupId>xml-apis</groupId>
@@ -62,7 +62,7 @@
<dependency> <dependency>
<groupId>com.github.jai-imageio</groupId> <groupId>com.github.jai-imageio</groupId>
<artifactId>jai-imageio-jpeg2000</artifactId> <artifactId>jai-imageio-jpeg2000</artifactId>
<version>1.4.0</version> <version>1.3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.levigo.jbig2</groupId> <groupId>com.levigo.jbig2</groupId>
@@ -77,12 +77,12 @@
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId> <artifactId>bootstrap</artifactId>
<version>5.1.3</version> <version>5.3.7</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.webjars</groupId> <groupId>org.webjars</groupId>
<artifactId>jquery</artifactId> <artifactId>jquery</artifactId>
<version>3.6.0</version> <version>3.7.1</version>
</dependency> </dependency>
<dependency> <dependency>

Ver fichero

@@ -4,12 +4,10 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration; import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveElasticsearchClient; import org.springframework.data.elasticsearch.client.elc.ReactiveElasticsearchConfiguration;
import org.springframework.data.elasticsearch.client.reactive.ReactiveRestClients;
import org.springframework.data.elasticsearch.config.AbstractReactiveElasticsearchConfiguration;
@Configuration @Configuration
public class ESConfig extends AbstractReactiveElasticsearchConfiguration { public class ESConfig extends ReactiveElasticsearchConfiguration {
@Value("${elasticsearch.host}") @Value("${elasticsearch.host}")
private String EsHost; private String EsHost;
@@ -24,11 +22,10 @@ public class ESConfig extends AbstractReactiveElasticsearchConfiguration {
private String documentType; private String documentType;
@Override @Override
@Bean public ClientConfiguration clientConfiguration() {
public ReactiveElasticsearchClient reactiveElasticsearchClient() { return ClientConfiguration.builder()
final ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo(EsHost + ":" + EsPort) .connectedTo(EsHost + ":" + EsPort)
.build(); .build();
return ReactiveRestClients.create(clientConfiguration);
} }
@Bean @Bean

Ver fichero

@@ -3,34 +3,31 @@ package com.manalejandro.arjion2.services;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.manalejandro.arjion2.model.Consulta;
import com.manalejandro.arjion2.model.Documento;
import com.manalejandro.arjion2.repositories.MainRepository;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
import org.elasticsearch.search.suggest.SuggestBuilder;
import org.elasticsearch.search.suggest.SuggestBuilders;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContext;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.client.elc.NativeQuery;
import org.springframework.data.elasticsearch.core.ReactiveElasticsearchOperations;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.manalejandro.arjion2.model.Consulta;
import com.manalejandro.arjion2.model.Documento;
import com.manalejandro.arjion2.repositories.MainRepository;
import co.elastic.clients.elasticsearch._types.FieldValue;
import co.elastic.clients.elasticsearch._types.query_dsl.BoolQuery;
import co.elastic.clients.elasticsearch._types.query_dsl.Query;
import co.elastic.clients.elasticsearch._types.query_dsl.RangeQuery;
@Service @Service
public class MainServiceImpl implements MainService { public class MainServiceImpl implements MainService {
private final ApplicationContext appContext; private final ApplicationContext appContext;
private final MainRepository mainRepository; private final MainRepository mainRepository;
private final ReactiveElasticsearchOperations elasticsearchOperations;
@Value("#{@indexName}") @Value("#{@indexName}")
private String index; private String index;
@@ -38,9 +35,10 @@ public class MainServiceImpl implements MainService {
private String document; private String document;
@Autowired @Autowired
public MainServiceImpl(MainRepository mainRepository, ApplicationContext appContext) { public MainServiceImpl(MainRepository mainRepository, ApplicationContext appContext, ReactiveElasticsearchOperations elasticsearchOperations) {
this.mainRepository = mainRepository; this.mainRepository = mainRepository;
this.appContext = appContext; this.appContext = appContext;
this.elasticsearchOperations = elasticsearchOperations;
} }
@Override @Override
@@ -76,52 +74,76 @@ public class MainServiceImpl implements MainService {
@Override @Override
public Consulta search(String busqueda, String[] tipo, Integer tamano, Pageable pageable) { public Consulta search(String busqueda, String[] tipo, Integer tamano, Pageable pageable) {
Client client = (Client) appContext.getBean("client"); // Build the bool query
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery(); BoolQuery.Builder boolQueryBuilder = new BoolQuery.Builder();
if (busqueda != null && !"null".equals(busqueda) && !busqueda.isEmpty()) { if (busqueda != null && !"null".equals(busqueda) && !busqueda.isEmpty()) {
boolQueryBuilder.must(QueryBuilders.matchQuery("nombre", busqueda)); // Add match query for nombre
boolQueryBuilder.should(QueryBuilders.matchQuery("contenido", busqueda)); boolQueryBuilder.must(Query.of(q -> q
.match(m -> m
.field("nombre")
.query(busqueda)
)
));
// Add should query for contenido
boolQueryBuilder.should(Query.of(q -> q
.match(m -> m
.field("contenido")
.query(busqueda)
)
));
} }
if (tipo != null && tipo.length > 0)
boolQueryBuilder.filter(QueryBuilders.termsQuery("tipo", tipo)); if (tipo != null && tipo.length > 0) {
if (tamano != null && tamano >= 0) // Add terms filter for tipo
boolQueryBuilder.must(QueryBuilders.rangeQuery("tamano").to(tamano).includeUpper(true)); List<FieldValue> tipoValues = new ArrayList<>();
AggregationBuilder aggregation = AggregationBuilders.terms("by_xarchivo").field("x_archivo").size(10000); for (String t : tipo) {
SuggestBuilder suggest = new SuggestBuilder() tipoValues.add(FieldValue.of(t));
.addSuggestion("suggest", SuggestBuilders.completionSuggestion("nombre").text(busqueda).size(10))
.addSuggestion("phrase", SuggestBuilders.phraseSuggestion("nombre").text(busqueda).size(1)
.realWordErrorLikelihood((float) 0.95).maxErrors((float) 0.5).gramSize(2));
System.out.println(boolQueryBuilder);
SearchResponse response = client.prepareSearch(index).setQuery(boolQueryBuilder).addAggregation(aggregation)
.suggest(suggest).setSize(pageable.getPageSize()).setFrom(pageable.getPageNumber()).execute()
.actionGet();
Consulta consulta = new Consulta();
consulta.setSuggest(response.getSuggest().getSuggestion("phrase").getEntries().get(0).getOptions().size() > 0
? response.getSuggest().getSuggestion("phrase").getEntries().get(0).getOptions().get(0).getText()
.string()
: "");
for (Entry<? extends Option> entry : response.getSuggest().getSuggestion("suggest").getEntries()) {
entry.getOptions().forEach(option -> {
String suggestText = option.getText().string().trim(),
autocompleteClean = busqueda.replaceAll("[^\\p{Alnum}\\p{IsAlphabetic} ]", "");
for (String item : autocompleteClean.split(" ")) {
if (item.length() > 0) {
consulta.getAutocomplete().add(
suggestText.replaceAll("(?i)((?!<)" + item + "(?![^<>]*>))", "<strong>$1</strong>"));
}
}
});
}
ObjectMapper mapper = new ObjectMapper();
List<Documento> documentos = new ArrayList<Documento>();
if (response.getHits().getHits().length > 0) {
try {
documentos = mapper.reader().readValue(response.getHits().getHits().toString());
} catch (JsonProcessingException e) {
e.printStackTrace();
} }
boolQueryBuilder.filter(Query.of(q -> q
.terms(t -> t
.field("tipo")
.terms(tv -> tv.value(tipoValues))
)
));
} }
consulta.setDocumentos(documentos);
if (tamano != null && tamano >= 0) {
// Add range query for tamano
boolQueryBuilder.must(Query.of(q -> q
.range(RangeQuery.of(r -> r
.number(n -> n
.field("tamano")
.lte((double) tamano)
)
))
));
}
// Create the native query
Query query = Query.of(q -> q.bool(boolQueryBuilder.build()));
NativeQuery nativeQuery = NativeQuery.builder()
.withQuery(query)
.withPageable(pageable)
.build();
// Execute the search
List<Documento> documentos = elasticsearchOperations
.search(nativeQuery, Documento.class)
.map(SearchHit::getContent)
.collectList()
.block();
// Create consulta response
Consulta consulta = new Consulta();
consulta.setDocumentos(documentos != null ? documentos : new ArrayList<>());
// Note: Suggestions and aggregations functionality has been simplified
// The new API requires different implementation for suggestions
// You may need to implement this separately if needed
consulta.setSuggest("");
consulta.setAutocomplete(new ArrayList<>());
return consulta; return consulta;
} }
} }