1

Lucene 3.6 を使用して Java でアプリケーションを作成しており、増分レートを作成したいと考えています。私はすでにインデックスを作成しました。既存のインデックスを開き、各ドキュメントのインデックス作成日とドキュメントの変更日を確認して、インデックス ファイルを削除し、再度追加する必要があることを読みました。私の問題は、Java Lucene でそれを行う方法がわからないことです。

ありがとう

私のコードは次のとおりです。

public static void main(String[] args) 
    throws CorruptIndexException, LockObtainFailedException,
           IOException {

    File docDir = new File("D:\\PRUEBASLUCENE");
    File indexDir = new File("C:\\PRUEBA");

    Directory fsDir = FSDirectory.open(indexDir);
    Analyzer an = new StandardAnalyzer(Version.LUCENE_36);
    IndexWriter indexWriter
        = new IndexWriter(fsDir,an,MaxFieldLength.UNLIMITED);


    long numChars = 0L;
    for (File f : docDir.listFiles()) {
        String fileName = f.getName();
        Document d = new Document();
        d.add(new Field("Name",fileName,
                        Store.YES,Index.NOT_ANALYZED));
        d.add(new Field("Path",f.getPath(),Store.YES,Index.ANALYZED));
        long tamano = f.length();
        d.add(new Field("Size",""+tamano,Store.YES,Index.ANALYZED));
        long fechalong = f.lastModified();
        d.add(new Field("Modification_Date",""+fechalong,Store.YES,Index.ANALYZED));
        indexWriter.addDocument(d);
    }

    indexWriter.optimize();
    indexWriter.close();
    int numDocs = indexWriter.numDocs();

    System.out.println("Index Directory=" + indexDir.getCanonicalPath());
    System.out.println("Doc Directory=" + docDir.getCanonicalPath());
    System.out.println("num docs=" + numDocs);
    System.out.println("num chars=" + numChars);

}


Edmondo1984 に感謝します。

最後に、以下に示すようにコードを実行しました。ファイルのハッシュを保存し、変更日を確認します。

9300 のインデックス ファイルでは 15 秒かかり、インデックスの再作成 (ファイルがないため変更されていないインデックスなし) には 15 秒かかります。私は何か間違ったことをしていますか、それともコードを最適化してより少なくすることができますか?


jtahlborn に感謝します。indexReader の作成と更新の時間を均等にすることができました。既存のインデックスを更新して再作成する方が速いはずではありませんか? コードをさらに最適化することは可能ですか?

if(IndexReader.indexExists(dir))
            {
                //reader is a IndexReader and is passed as parameter to the function
                //searcher is a IndexSearcher and is passed as parameter to the function
                term = new Term("Hash",String.valueOf(file.hashCode()));
                Query termQuery = new TermQuery(term);
                TopDocs topDocs = searcher.search(termQuery,1);
                if(topDocs.totalHits==1)
                {
                    Document doc;
                    int docId,comparedate;
                    docId=topDocs.scoreDocs[0].doc;
                    doc=reader.document(docId);
                    String dateIndString=doc.get("Modification_date");
                    long dateIndLong=Long.parseLong(dateIndString);
                    Date date_ind=new Date(dateIndLong);
                    String dateFichString=DateTools.timeToString(file.lastModified(), DateTools.Resolution.MINUTE);
                    long dateFichLong=Long.parseLong(dateFichString);
                    Date date_fich=new Date(dateFichLong);
                    //Compare the two dates
                    comparedates=date_fich.compareTo(date_ind);
                    if(comparedate>=0)
                    {
                        if(comparedate==0)
                        {
                            //If comparation is 0 do nothing
                            flag=2;
                        }
                        else
                        {
                            //if comparation>0 updateDocument
                            flag=1;
                        }
                    }
4

1 に答える 1

4

Lucene データ モデルに従って、インデックス内にドキュメントを格納します。各ドキュメント内には、インデックスを作成するフィールド (いわゆる「分析済み」) と、タイムスタンプや後で必要になる可能性のあるその他の情報を保存できる「分析済み」ではないフィールドがあります。

最初の投稿でドキュメントについて話し、現在は IndexFileNames.isDocStoreFile(file.getName()) を呼び出そうとしているため、ファイルとドキュメントの間に特定の混乱があると感じています。 Lucene インデックス。

Lucene オブジェクト モデルを理解していれば、必要なコードを記述するのに約 3 分かかります。

  • 単純に Lucene にクエリを実行して、ドキュメントがインデックスに既に存在するかどうかを確認する必要があります (たとえば、一意の識別子を含む分析されていないフィールドを格納することにより)。
  • クエリが 0 ドキュメントを返す場合、新しいドキュメントをインデックスに追加します
  • クエリが 1 つのドキュメントを返す場合、その「タイムスタンプ」フィールドを取得し、保存しようとしている新しいドキュメントの 1 つと比較します。次に、ドキュメントの docId を使用してインデックスからドキュメントを削除し、必要に応じて新しいドキュメントを追加できます。

反対に、以前の値を常に変更したい場合は、Lucene in Action の次のスニペットを参照できます。

public void testUpdate() throws IOException { 
    assertEquals(1, getHitCount("city", "Amsterdam"));
    IndexWriter writer = getWriter();
    Document doc = new Document();
    doc.add(new Field("id", "1",
    Field.Store.YES,
    Field.Index.NOT_ANALYZED));
    doc.add(new Field("country", "Netherlands",
    Field.Store.YES,
    Field.Index.NO));
    doc.add(new Field("contents",
    "Den Haag has a lot of museums",
    Field.Store.NO,
    Field.Index.ANALYZED));
    doc.add(new Field("city", "Den Haag",
    Field.Store.YES,
    Field.Index.ANALYZED));
    writer.updateDocument(new Term("id", "1"),
    doc);
    writer.close();
    assertEquals(0, getHitCount("city", "Amsterdam"));
    assertEquals(1, getHitCount("city", "Den Haag"));
}

ご覧のとおり、スニペットは分析されていない ID を使用しています。クエリ可能な単純な属性を保存し、updateDocument メソッドを使用してドキュメントを最初に削除してから再度追加することを提案したためです。

次の javadoc を直接確認することをお勧めします。

http://lucene.apache.org/core/3_6_0/api/all/org/apache/lucene/index/IndexWriter.html#updateDocument(org.apache.lucene.index.Term,org.apache.lucene.document.文書)

于 2012-07-17T06:48:00.780 に答える