0

私は Lucene 5.3 を使用し、queryparser-syntax を使用して複数のフィールドを検索しようとしています。Lucene チュートリアル内で短い例を見つけて、それをバージョン 5.3 に変更し、それらのフィールドを検索しました。

package lucenewriterexample;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.RAMDirectory;

import java.io.IOException;

public class LuceneWriterExample {


    public static void main(String[] args) throws IOException, ParseException {
        StandardAnalyzer analyzer = new StandardAnalyzer();
        Directory index = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        try (IndexWriter writer = new IndexWriter(index, config)) {
            addDoc(writer, "Day first : Lucence Introduction test.", "3436NRX");
            addDoc(writer, "Day second , part one : Lucence Projects.", "3437RJ1");
            addDoc(writer, "Day second , part two: Lucence Uses testing rr.", "3437RJ2");
            addDoc(writer, "Day third : Lucence Demos.", "34338KRX");
        }

        String querystr = "title:(part) AND course_code:(3437RJ1)";
        Query q = new QueryParser("title", analyzer).parse(querystr);

        // 3. searching
        int hitsPerPage = 10;
        IndexReader reader = DirectoryReader.open(index);
        IndexSearcher searcher = new IndexSearcher(reader);
        TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage);
        searcher.search(q, collector);
        ScoreDoc[] hits = collector.topDocs().scoreDocs;

        // 4. display results
        System.out.println("Query string: " + querystr );
        System.out.println("Found " + hits.length + " hits.");        
        for (int i = 0; i < hits.length; ++i) {
            int docId = hits[i].doc;
            Document d = searcher.doc(docId);
            System.out.println((i + 1) + ". " + d.get("course_code") + "\t" + d.get("title"));
        }

        // Finally , close reader
    }

    private static void addDoc(IndexWriter w, String title, String courseCode) throws IOException {
        Document doc = new Document();
        doc.add(new TextField  ("title",       title,      Field.Store.YES));
        doc.add(new StringField("course_code", courseCode, Field.Store.YES));
        w.addDocument(doc);
    }

クエリパーサーは「title:part」に対して機能しており、「part」を含むすべてのドキュメントを取得しますが、「title:(part) AND course_code:(3437RJ1)」または「title:(part) OR course_code:(3436NRX)」を使用すると、 ) 結果は 0 です。検索のどこが間違っていますか?

4

1 に答える 1

1

これを実行して を試したところtitle:(part) OR course_code:(3436NRX)、予想どおり 2 つの結果が得られました。おそらく、course_code に一致する 3 番目の結果を期待していたのに、それを取得できなかったということです。そのクエリで実際にゼロの結果が得られたという意味であれば、何が問題なのかわかりません。

では、なぜ course_code で一致を取得できないのでしょうか?

lucene の場合によくあることですが、アナライザーが一致していません。queryparser は を使用してStandardAnalyzerいますが、 course_code は であるStringFieldため、まったく分析されていません。StandardAnalyzer にはすべてを小文字にするフィルターが含まれているため、最終的には、 を含むフィールド3436NRXと のクエリが作成されcourse_code:3436nrxます。

考えられる解決策は次のとおりです。

  • s のTermQueryクエリ パーサーの代わりにa を使用しますStringField
  • lucene に渡す前に自分で course_code を小文字にします
  • course_code をTextField

于 2015-09-18T14:20:12.633 に答える