2

小さなファイルにインデックスを付けるサンプルのLuceneコードスニペットを作成しました。インデックス作成を正しく実行し、単一のフィールド値を検索することができます。しかし、私は複数のフィールドでクエリを実行したいと思います。を使用してBooleanQueryいますが、機能していません。

誰かが提案できますか?これが私のコードスニペットです。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.SimpleFSDirectory;
import org.apache.lucene.util.Version;

public class LocalFSLucene {

    private final Version version = Version.LUCENE_36;

    private final String indexDirectory = "/Work/Lucene/LocalFSIndex";

    private final String dataFile = "/Work/Lucene/data.txt";

    private final String fields[] = {"date", "time", "cs-method", "cs-uri",
                                     "sc-status", "time-taken"};

    private IndexWriterConfig config = null;

    public void setConfig() {

        /* Check if the IndexWriterConfiguration is available or not.
         * If not, we will create one and save it for any further references.
         */
        if (config == null) {
            config = new IndexWriterConfig(version, new StandardAnalyzer(version));
        }
    }

    private final String rowDelimiter = " ";
    public void buildIndex() throws Exception {

        /* Create the Configuration object for writing index files */
        setConfig();

        /* Get the handle to the directory where indexes will be created */
        Directory dir = new SimpleFSDirectory(new File(indexDirectory));

        /* Initialize the index writer object */
        IndexWriter indexWriter = new IndexWriter(dir, config);

        /* Reader object to read the data file */
        BufferedReader reader = new BufferedReader(new FileReader(dataFile));

        /* Read each line of the data and build the index on the fields */
        String row = null;

        while ((row = reader.readLine()) != null) {

            /* Get each field in the current row */
            String fieldValues[] = row.split(rowDelimiter);

            /* Create a document for each row to store the index information */
            Document doc = new Document();

            for (int i = 0; i < fields.length; i++) {
                doc.add(new Field(fields[i], fieldValues[i], Field.Store.YES, Field.Index.ANALYZED));
            }

            /* Add the document to index */
            indexWriter.addDocument(doc);
        }

        /* Push the index files on the File System */
        indexWriter.commit();

        /* Close the reader object */
        reader.close();

        /* Close the index writer object */
        indexWriter.close();

        System.out.println("Indexing is complete");
    }

    public void search(Map<String, String> params) throws Exception {

        /* Get the handle to the directory where indexes are be created */
        Directory dir = new SimpleFSDirectory(new File(indexDirectory));

        /* Create the Index Reader object to read the indexes created */
        IndexReader reader = IndexReader.open(dir);

        /* Create the detective object which will perform search operation */
        IndexSearcher detective = new IndexSearcher(reader);

        System.out.println("Total Number of Documents - " + detective.maxDoc());

        /* Build the query containing the clues which the detective will use
         * to solve the case.
         */
        //Query q = new QueryParser(version, field, new StandardAnalyzer(version)).parse(value);
        BooleanQuery q = new BooleanQuery();

        Set<String> fields = params.keySet();

        for (String field : fields) {
            q.add(new TermQuery(new Term(field, params.get(field))), BooleanClause.Occur.SHOULD);
        }

        /* The TopScoreDocCollector will create the bag where the detective will
         * put all the found clues to solve the case.
         */
        TopScoreDocCollector clueBag = TopScoreDocCollector.create(10, true);

        /* Ask the detective to start */
        detective.search(q, clueBag);

        /* Get all the clues which the detective found during investigation
         * and display them.
         */
        ScoreDoc clues[] = clueBag.topDocs().scoreDocs;

        System.out.println("Total Clues Found - " + clues.length);
        System.out.println();

        for (int i = 0; i < clues.length; i++) {

            /* Get the pointer to the clue */
            int clueId = clues[i].doc;

            /* Get the actual clue from the clue bag */
            Document clue = detective.doc(clueId);

            /* Print the document */
            List<Fieldable> lstFields = clue.getFields();

            System.out.print((i + 1) + " --> ");
            for (Fieldable fld : lstFields) {

                String strField = fld.name();

                String strValue = clue.get(strField);

                System.out.print(strField + ":" + strValue + "  ");
            }
            System.out.println();
        }
    }

    public static void main(String args[]) throws Exception {
        LocalFSLucene obj = new LocalFSLucene();

        //obj.buildIndex();

        Map<String, String> searchParams = new HashMap<String, String>();
        searchParams.put("cs-method", "GET");
        searchParams.put("cs-uri", "/blank");
        obj.search(searchParams);
    }
}

これが私data.txtが使っているものです。

2010-04-21 02:24:01 GET /blank 200 120
2010-04-21 02:24:01 GET /US/registrationFrame 200 605
2010-04-21 02:24:02 GET /US/kids/boys 200 785
2010-04-21 02:24:02 POST /blank 304 56
2010-04-21 02:24:04 GET /blank 304 233
2010-04-21 02:24:04 GET /blank 500 567
2010-04-21 02:24:04 GET /blank 200 897
2010-04-21 02:24:04 POST /blank 200 567
2010-04-21 02:24:05 GET /US/search 200 658
2010-04-21 02:24:05 POST /US/shop 200 768
2010-04-21 02:24:05 GET /blank 200 347
4

2 に答える 2

3

ついにそれが機能するようになりました。これがあなたがそれを使うことを想定している方法です。

  1. BooleanQueryフィールドとパラメータを使用してクエリを作成します。
  2. BooleanQueryを使用して解析する文字列を渡しQueryParserます。

これが同じスニペットです。

BooleanQuery b = new BooleanQuery();

Set<String> fields = params.keySet();
StandardAnalyzer analyzer = new StandardAnalyzer(version);

b.add(new TermQuery(new Term("cs-method", "GET"), BooleanClause.Occur.SHOULD);
b.add(new TermQuery(new Term("cs-uri", "/blank"), BooleanClause.Occur.SHOULD);

Query q = new QueryParser(version, "cs-method", analyzer).parse(b.toString());
于 2012-08-03T08:00:30.060 に答える
1

main()上記のコードスニペットの下にあるメソッドは次のとおりです。

public static void main(String args[]) throws Exception {
    LocalFSLucene obj = new LocalFSLucene();

    //obj.buildIndex();

    Map<String, String> searchParams = new HashMap<String, String>();
    searchParams.put("cs-method", "GET");
    searchParams.put("cs-uri", "/blank");
    obj.search(searchParams);
}

また、出力は次のとおりです。

Total Number of Documents - 11
Total Clues Found - 0

QueryParserとのクエリは異なりBooleanQueryます。他のバージョンにはないバージョンの+サインが表示されます。QueryParser以下を確認してください。

使用するQueryParser

Query q = new QueryParser(version, "cs-method", new StandardAnalyzer(version)).parse("cs-method:GET AND cs-uri:/blank");

の出力QueryParser

Total Number of Documents - 11
Query --> +cs-method:get +cs-uri:blank
Total Clues Found - 5

使用するBooleanQuery

Map<String, String> searchParams = new HashMap<String, String>();
searchParams.put("cs-method", "GET");
searchParams.put("cs-uri", "/blank");
BooleanQuery q = new BooleanQuery();

Set<String> fields = params.keySet();
for (String field : fields) {
    q.add(new TermQuery(new Term(field, params.get(field))), BooleanClause.Occur.SHOULD);
}

の出力BooleanQuery

Total Number of Documents - 11
Query --> cs-method:GET cs-uri:/blank
Total Clues Found - 0
于 2012-07-19T18:03:19.407 に答える