sintaxis - Búsqueda difusa de Lucene en una frase(FuzzyQuery+SpanQuery)
fuzzy query lucene (2)
Estoy buscando una forma de codificar la consulta borrosa lucene que busca todos los documentos, que son relevantes para una frase exacta. Si busco "mosa employee appreciata", se devolverá como resultado un documento que contenga "la mayoría de los empleados aprecian".
Intenté usar:
FuzzyQeury = new FuzzyQuery(new Term("contents","mosa employee appreicata"))
Lamentablemente, empíricamente no funciona. El FuzzyQuery emplea la distancia del editor; teóricamente, "mosa employee appreciata" debe coincidir con "la mayoría de los empleados aprecian" proporcionar la distancia adecuada. Parece un poco extraño.
¿Alguna pista? Gracias.
Aquí hay dos problemas probables. Primero: supongo que el campo de "contenidos" se está analizando de modo que "la mayoría de los empleados lo aprecien" no es un término, sino tres términos. Definir como un solo término no es apropiado en este caso.
Sin embargo, incluso si el contenido enumerado es un término único, un segundo problema probable que tenemos es que hay demasiada distancia entre los términos para obtener una coincidencia. La distancia de Damerau-Levenshtein entre el mosa employee appreicata
y la most employees appreciate
es de 4 (la distancia aproximada, por cierto, entre mi primer intento promedio de deletrear "Damerau-Levenshtein" y la ortografía correcta). Fuzzy Query, a partir de 4.0, maneja distancias de edición de no más de 2, debido a restricciones de rendimiento, y la suposición de que las distancias más grandes generalmente no son particularmente relevantes.
Si necesita realizar una consulta de frase con términos difusos, debe buscar en MultiPhraseQuery
o combinar un conjunto de SpanQueries
(especialmente SpanMultiTermQueryWrapper
y SpanNearQuery
) para satisfacer sus necesidades.
SpanQuery[] clauses = new SpanQuery[3];
clauses[0] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "mosa")));
clauses[1] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "employee")));
clauses[2] = new SpanMultiTermQueryWrapper(new FuzzyQuery(new Term("contents", "appreicata")));
SpanNearQuery query = new SpanNearQuery(clauses, 0, true)
Y dado que ninguno de los términos individuales tiene una distancia de edición mayor a 2, esto debería ser más efectivo.
¡La respuesta de FemtoRgon es genial! Gracias.
Hay otra forma de resolver este problema.
//declare a mutilphrasequery
MultiPhraseQuery childrenInOrder = new MultiPhraseQuery();
//user fuzzytermenum to enumerate your query string
FuzzyTermEnum fuzzyEnumeratedTerms1 = new FuzzyTermEnum(reader, new Term(searchField,"mosa"));
FuzzyTermEnum fuzzyEnumeratedTerms2 = new FuzzyTermEnum(reader, new Term(searchField,"employee"));
FuzzyTermEnum fuzzyEnumeratedTerms3 = new FuzzyTermEnum(reader, new Term(searchField,"appreicata"));
//this basically pull out the possbile terms from the index
Term termHolder1 = fuzzyEnumeratedTerms1.term();
Term termHolder2 = fuzzyEnumeratedTerms2.term();
Term termHolder3 = fuzzyEnumeratedTerms3.term();
//put the possible terms into multiphrasequery
if (termHolder1==null){
childrenInOrder.add(new Term(searchField,"mosa"));
}else{
childrenInOrder.add(fuzzyEnumeratedTerms1.term());
}
if (termHolder2==null){
childrenInOrder.add(new Term(searchField,"employee"));
}else{
childrenInOrder.add(fuzzyEnumeratedTerms2.term());
}
if (termHolder3==null){
childrenInOrder.add(new Term(searchField,"appreicata"));
}else{
childrenInOrder.add(fuzzyEnumeratedTerms3.term());
}
//close it - it is important to close it
fuzzyEnumeratedTerms1.close();
fuzzyEnumeratedTerms2.close();
fuzzyEnumeratedTerms3.close();