java - for - Cómo buscar campos con comodín y espacios en Hibernate Search
hibernate search spring boot (2)
SQL usa diferentes comodines que cualquier terminal. En SQL ''%''
reemplaza cero o más apariciones de cualquier caracter (en el terminal usted usa ''*''
lugar), y el guion bajo ''_''
reemplaza exactamente un caracter (en el terminal usted usa ''?''
lugar). Hibernate no traduce los caracteres comodín.
Entonces, en la segunda línea, debe reemplazar la matching(searchString + "*")
con
matching(searchString + "%")
Tengo un cuadro de búsqueda que realiza una búsqueda en el campo de título en función de la entrada dada, por lo que el usuario ha recomendado todos los títulos disponibles a partir del texto insertado. Se basa en Lucene e Hibernate Search. Funciona bien hasta que se ingrese espacio. Entonces el resultado desaparecerá. Por ejemplo, quiero que "Learning H" me dé "Learning Hibernate" como resultado. Sin embargo, esto no sucede. ¿podría por favor aconsejarme qué debería usar aquí en su lugar?
Consultor de construcción:
QueryBuilder qBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(LearningGoal.class).get();
Query query = qBuilder.keyword().wildcard().onField("title")
.matching(searchString + "*").createQuery();
BooleanQuery bQuery = new BooleanQuery();
bQuery.add(query, BooleanClause.Occur.MUST);
for (LearningGoal exGoal : existingGoals) {
Term omittedTerm = new Term("id", String.valueOf(exGoal.getId()));
bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT);
}
@SuppressWarnings("unused")
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
query, LearningGoal.class);
Clase de Hibernate :
@AnalyzerDef(name = "searchtokenanalyzer",tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class),
filters = {
@TokenFilterDef(factory = StandardFilterFactory.class),
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = StopFilterFactory.class,params = {
@Parameter(name = "ignoreCase", value = "true") }) })
@Analyzer(definition = "searchtokenanalyzer")
public class LearningGoal extends Node {
Encontré una solución para este problema. La idea es tokenizar cadena de entrada y eliminar palabras de parada. Para el último token creé una consulta usando el comodín de la palabra clave, y para todas las palabras anteriores creé un TermQuery. Aquí está el código completo
BooleanQuery bQuery = new BooleanQuery();
Session session = persistence.currentManager();
FullTextSession fullTextSession = Search.getFullTextSession(session);
Analyzer analyzer = fullTextSession.getSearchFactory().getAnalyzer("searchtokenanalyzer");
QueryParser parser = new QueryParser(Version.LUCENE_35, "title", analyzer);
String[] tokenized=null;
try {
Query query= parser.parse(searchString);
String cleanedText=query.toString("title");
tokenized = cleanedText.split("//s");
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
QueryBuilder qBuilder = fullTextSession.getSearchFactory()
.buildQueryBuilder().forEntity(LearningGoal.class).get();
for(int i=0;i<tokenized.length;i++){
if(i==(tokenized.length-1)){
Query query = qBuilder.keyword().wildcard().onField("title")
.matching(tokenized[i] + "*").createQuery();
bQuery.add(query, BooleanClause.Occur.MUST);
}else{
Term exactTerm = new Term("title", tokenized[i]);
bQuery.add(new TermQuery(exactTerm), BooleanClause.Occur.MUST);
}
}
for (LearningGoal exGoal : existingGoals) {
Term omittedTerm = new Term("id", String.valueOf(exGoal.getId()));
bQuery.add(new TermQuery(omittedTerm), BooleanClause.Occur.MUST_NOT);
}
org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery(
bQuery, LearningGoal.class);