2011-04-01 18 views
7

Usamos Lucene para indexar algunos documentos internos. A veces necesitamos eliminar documentos. Estos documentos tienen un identificador único y están representados por un DocItem clase de la siguiente manera (todo el código es una versión simplificada CON SOLO significativa (espero) PARTES):Lucene 3.0.3 no elimina el documento

public final class DocItem { 

    public static final String fID = "id"; 
    public static final String fTITLE = "title"; 

    private Document doc = new Document(); 
    private Field id = new Field(fID, "", Field.Store.YES, Field.Index.ANALYZED); 
    private Field title = new Field(fTITLE, "", Field.Store.YES, Field.Index.ANALYZED); 

    public DocItem() { 
    doc.add(id); 
    doc.add(title); 
    } 

    ... getters & setters 

    public getDoc() { 
    return doc; 
    } 
} 

Así, el índice de un documento, un nuevo DocItem se crea y se pasa a una clase de controlador paso a paso de la siguiente manera:

public static void index(DocItem docitem) { 
    File file = new File("indexdir"); 
    Directory dir= new SimpleFSDirectory(file); 
    IndexWriter idxWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED); 
    idxWriter.addDocument(docitem.getDoc()); 
    idxWriter.close(); 
} 

hemos creado un método auxiliar para iterar sobre el directorio de índice:

public static void listAll() { 
    File file = new File("indexdir"); 
    Directory dir = new SimpleFSDirectory(file); 
    IndexReader reader = IndexReader.open(dir); 

    for (int i = 0; i < reader.maxDoc(); i++) { 
    Document doc = reader.document(i); 
    System.out.println(doc.get(DocItem.fID)); 
    } 
} 

Ejecución del listAll, podemos ver que nuestros documentos están siendo indexados correctamente Al menos, podemos ver la identificación y otros atributos.

recuperamos el documento mediante IndexSearcher de la siguiente manera:

public static DocItem search(String id) { 
    File file = new File("indexdir"); 
    Directory dir = new SimpleFSDirectory(file); 
    IndexSearcher searcher = new IndexSearcher(index, true); 
    Query q = new QueryParser(Version.LUCENE_30, DocItem.fID, new StandardAnalyzer(Version.LUCENE_30)).parse(id); 
    TopDocs td = searcher.search(q, 1); 
    ScoreDoc[] hits = td.scoreDocs; 
    searcher.close(); 
    return hits[0]; 
} 

Así que después de recuperarla, estamos tratando de eliminarlo con:

public static void Delete(DocItem docitem) { 
    File file = new File("indexdir"); 
    Directory dir= new SimpleFSDirectory(file); 
    IndexWriter idxWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED); 
    idxWriter.deleteDocuments(new Term(DocItem.fID, docitem.getId())); 
    idxWriter.commit(); 
    idxWriter.close(); 
} 

El problema es que no funciona. El documento nunca se borra. Si ejecuto listAll() después de la eliminación, el documento aún está allí. Intentamos usar IndexReader, sin suerte.

Por este post y este post, Creemos que lo estamos usando de acuerdo.

¿Qué estamos haciendo mal? ¿Algún consejo? Estamos usando lucene 3.0.3 y java 1.6.0_24.

TIA,

Bob

Respuesta

0
public static void Delete(DocItem docitem) { 
    File file = new File("indexdir"); 
    Directory dir= new SimpleFSDirectory(file); 
    IndexWriter idxWriter = new IndexWriter(dir, new StandardAnalyzer(Version.LUCENE_30), IndexWriter.MaxFieldLength.UNLIMITED); 
    idxWriter.deleteDocuments(new Term(DocItem.fID, docitem.getId())); 
    idxWriter.commit(); 
    idxWriter.close(
3

Yo sugeriría, utilice IndexReader DeleteDocumets, devuelve el número de documentos eliminados. esto te ayudará a reducir si las eliminaciones se producen en el primer recuento.

la ventaja de este método sobre el IndexWriter, es que se devuelve el documento total de borrado, si ninguno si se devuelve 0.

Véase también la How do I delete documents from the index? y this posterior

Editar: También me di cuenta de que abrir el modo de sólo lectura indexreader en, puede cambiar los listFiles() lector índice open con falso como segundo parámetro, esto permitirá lectura y escritura, tal vez la fuente de error

1

llamo IndexWriterConfig#setMaxBufferedDeleteTerms(1) durante IndexWriter instanciación/configuración y todas las operaciones de eliminación van al disco inmediatamente. Tal vez no sea correcto en cuanto al diseño, pero resuelve el problema explicado aquí.

Cuestiones relacionadas