tag questions endings search lucene sentence

search - questions - Búsqueda consciente de frases con Lucene SpanQueries



tag endings (2)

¿Es posible usar un Lucene SpanQuery para encontrar todas las ocurrencias donde los términos "rojo", "verde" y "azul" aparecen dentro de una sola oración?

Mi primer enfoque (incompleto / incorrecto) es escribir un analizador que coloca un token marcador de oraciones especial y el comienzo de una oración en la misma posición que la primera palabra de la oración y luego buscar algo similar a lo siguiente:

SpanQuery termsInSentence = new SpanNearQuery( SpanQuery[] { new SpanTermQuery( new Term (MY_SPECIAL_SENTENCE_TOKEN)), new SpanTermQuery( new Term ("red")), new SpanTermQuery( new Term ("green")), new SpanTermQuery( new Term ("blue")), }, 999999999999, false ); SpanQuery nextSentence = new SpanTermQuery( new Term (MY_SPECIAL_SENTENCE_TOKEN)); SpanNotQuery notInNextSentence = new SpanNotQuery(termsInSentence,nextSentence);

El problema, por supuesto, es que nextSentence no es realmente la siguiente oración, es cualquier marcador de oraciones, incluido el que está en la oración que coincide con los termsInSentence . Por lo tanto, esto no funcionará.

Mi próximo enfoque es crear el analizador que coloca la ficha antes de la oración (es decir, antes de la primera palabra en lugar de en la misma posición que la primera palabra). El problema con esto es que luego tengo que dar cuenta de la compensación extra causada por MY_SPECIAL_SENTENCE_TOKEN . Lo que es más, esto será especialmente malo al principio cuando estoy usando un patrón ingenuo para dividir oraciones (por ejemplo, dividir en //./s+[A-Z0-9]/ ) porque tendré que dar cuenta de todos los Marcadores de oraciones (falso) cuando busco USS Enterprise .

Entonces ... ¿cómo debería abordar esto?


Yo indexaría cada oración como un documento de Lucene, incluyendo un campo que marca de qué documento origen proviene la oración. Dependiendo de su material de origen, la sobrecarga de la oración / LuceneDoc puede ser aceptable.


En realidad, parece que estás bastante cerca de la solución. Creo que indexar una bandera de final de frase es un buen enfoque. El problema es que tu bandera de final de frase está en tu SpanNearQuery , que es lo que te está tirando. Le está pidiendo que encuentre un tramo que contenga y no contenga MY_SPECIAL_SENTENCE_TOKEN . La consulta se contradice a sí misma, por lo que, por supuesto, no encontrará ninguna coincidencia. Lo que realmente necesita saber es que los tres términos ("rojo", "verde" y "azul") ocurren en un lapso que no se superpone con MY_SPECIAL_SENTENCE_TOKEN (es decir, el token de oración no aparece entre esos condiciones).

Además, la falta de nombres de campo en los diccionarios de Term sería un problema, pero Lucene debería lanzar una excepción quejándose de eso, así que adivinar que ese no es el verdadero problema aquí. Podría ser que la versión de Lucene en el momento en que se escribió esto no se quejó de los campos no coincidentes en SpanNears, por lo que quizás valga la pena mencionarlo.

Esto parece funcionar para mí:

SpanQuery termsInSentence = new SpanNearQuery( new SpanQuery[] { new SpanTermQuery( new Term ("text", "red")), new SpanTermQuery( new Term ("text", "green")), new SpanTermQuery( new Term ("text", "blue")), }, 9999, false ); SpanQuery nextSentence = new SpanTermQuery( new Term ("text", MY_SPECIAL_SENTENCE_TOKEN)); SpanQuery notInNextSentence = new SpanNotQuery(termsInSentence,nextSentence);

En cuanto a dónde dividir oraciones, en lugar de usar el enfoque naive regex, trataría de usar java.text.Breakiterator . No es perfecto, pero hace un trabajo bastante bueno.