0

私はただの lucene スターターであり、RAMDIrectory から FSDirectory への変更中に問題が発生しました。

最初に私のコード:

    private static IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_43,
            new StandardAnalyzer(Version.LUCENE_43));
    Directory DIR = FSDirectory.open(new File(INDEXLOC)); //INDEXLOC = "path/to/dir/"
    // RAMDirectory DIR = new RAMDirectory();

    // Index some made up content      
    IndexWriter writer =
            new IndexWriter(DIR, iwc);


    // Store both position and offset information
    FieldType type = new FieldType();
    type.setStored(true);
    type.setStoreTermVectors(true);
    type.setStoreTermVectorOffsets(true);
    type.setStoreTermVectorPositions(true);
    type.setIndexed(true);
    type.setTokenized(true);

    IDocumentParser p = DocumentParserFactory.getParser(f);
    ArrayList<ParserDocument> DOCS = p.getParsedDocuments();

    for (int i = 0; i < DOCS.size(); i++) {
        Document doc = new Document();
        Field id = new StringField("id", "doc_" + i, Field.Store.YES);
        doc.add(id);
        Field text = new Field("content", DOCS.get(i).getContent(), type);
        doc.add(text);
        writer.addDocument(doc);
    }
    writer.close();
    // Get a searcher
    IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(DIR));
    // Do a search using SpanQuery
    SpanTermQuery fleeceQ = new SpanTermQuery(new Term("content", "zahl"));
    TopDocs results = searcher.search(fleeceQ, 10);
    for (int i = 0; i < results.scoreDocs.length; i++) {
        ScoreDoc scoreDoc = results.scoreDocs[i];
        System.out.println("Score Doc: " + scoreDoc);
    }
    IndexReader reader = searcher.getIndexReader();

    AtomicReader wrapper = SlowCompositeReaderWrapper.wrap(reader);
    Map<Term, TermContext> termContexts = new HashMap<Term, TermContext>();
    Spans spans = fleeceQ.getSpans(wrapper.getContext(), new Bits.MatchAllBits(reader.numDocs()), termContexts);
    int window = 2;// get the words within two of the match
    while (spans.next() == true) {
        Map<Integer, String> entries = new TreeMap<Integer, String>();
        System.out.println("Doc: " + spans.doc() + " Start: " + spans.start() + " End: " + spans.end());
        int start = spans.start() - window;
        int end = spans.end() + window;
        Terms content = reader.getTermVector(spans.doc(), "content");
        TermsEnum termsEnum = content.iterator(null);
        BytesRef term;
        while ((term = termsEnum.next()) != null) {
            // could store the BytesRef here, but String is easier for this
            // example
            String s = new String(term.bytes, term.offset, term.length);
            DocsAndPositionsEnum positionsEnum = termsEnum.docsAndPositions(null, null);
            if (positionsEnum.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
                int i = 0;
                int position = -1;
                while (i < positionsEnum.freq() && (position = positionsEnum.nextPosition()) != -1) {
                    if (position >= start && position <= end) {
                        entries.put(position, s);
                    }
                    i++;
                }
            }
        }
        System.out.println("Entries:" + entries);
    }

それは私が素晴らしいウェブサイトで見つけたいくつかのコードであり、試してみたかった.... RAMDirectoryを使用するとすべてがうまく機能します。しかし、それを FSDirectory に変更すると、次のような NullpointerException が発生します。

com.org.test.Main.main(Main.java:31) の com.org.test.TextDB.myMethod(TextDB.java:184) でのスレッド「メイン」 java.lang.NullPointerException での例外

ステートメントTerms content = reader.getTermVector(spans.doc(), "content"); 結果が得られないようで、null を返します。だから例外。しかし、なぜ?私の ramDIR では、すべて正常に動作します。

indexWriter または Reader (実際にはわかりません) が、インデックスからフィールド "content" を適切に書き込んでいないか、読み取っていないようです。しかし、なぜそれが RAMDirectory に「書き込まれ」、FSDIrectory には書き込まれないのか、本当にわかりません。

誰でもそれについてのアイデアはありますか?

4

1 に答える 1

1

これを簡単にテストしてみましたが、問題を再現できません。

ここで最も可能性の高い問題は、インデックス内の古いドキュメントだと思います。この書き方では、実行するたびに、より多くのドキュメントがインデックスに追加されます。以前の実行からの古いドキュメントは削除または上書きされず、残ります。したがって、行を追加する前に同じディレクトリでこれを実行したことがtype.setStoreTermVectors(true);ある場合、結果の一部は用語ベクトルを含むこれらの古いドキュメントである可能性があり、ドキュメントに用語ベクトルreader.getTermVector(...)が保存されていない場合は null が返されます。

もちろん、 a でインデックス化されたものRAMDirectoryは実行が終了するとすぐに削除されるため、その場合は問題は発生しません。

簡単な解決策は、インデックス ディレクトリを削除してから再度実行することです。

これを実行するときに新しいインデックスから始めたい場合は、次のように設定できますIndexWriterConfig

private static IndexWriterConfig iwc = new IndexWriterConfig(Version.LUCENE_43,
        new StandardAnalyzer(Version.LUCENE_43));
iwc.setOpenMode(IndexWriterConfig.OpenMode.CREATE);

もちろん、それは推測ですが、あなたが説明した動作と一致しているようです。

于 2014-10-27T21:17:08.147 に答える