07_Lucene搜索

搜索

對(duì)要搜索的信息創(chuàng)建Query查詢對(duì)象,Lucene會(huì)根據(jù)Query查詢對(duì)象生成最終的查詢語法,類似關(guān)系數(shù)據(jù)庫(kù)Sql語法一樣Lucene也有自己的查詢語法,比如:“name:lucene”表示查詢Field的name為“l(fā)ucene”的文檔信息。
可通過兩種方法創(chuàng)建查詢對(duì)象:

  • 使用Lucene提供Query子類
    Query是一個(gè)抽象類,lucene提供了很多查詢對(duì)象,比如TermQuery項(xiàng)精確查詢,NumericRangeQuery數(shù)字范圍查詢等。
    如下代碼:
    Query query = new TermQuery(new Term("name", "lucene"));

  • 使用QueryParse解析查詢表達(dá)式
    QueryParse會(huì)將用戶輸入的查詢表達(dá)式解析成Query對(duì)象實(shí)例。
    如下代碼:
    QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
    Query query = queryParser.parse("name:lucene");

各種查詢

TermQuery:

根據(jù)詞進(jìn)行搜索(只能從文本中進(jìn)行搜索)
TermQuery,通過項(xiàng)查詢,TermQuery不使用分析器所以建議匹配不分詞的Field域查詢,比如訂單號(hào)、分類ID號(hào)等。指定要查詢的域和要查詢的關(guān)鍵詞。

    @Test
    public void testIndexTermQuery() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();

        //指定索引和文檔的目錄
        Directory dir  = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
        IndexReader indexReader = IndexReader.open(dir);

        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //創(chuàng)建詞元:就是詞,
        Term t = new Term("fileName" , "apache");
        //使用TermQuery查詢,根據(jù)term對(duì)象進(jìn)行查詢
        TermQuery query = new TermQuery(t);
        //搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
        TopDocs topdocs = indexSearcher.search(query , 10);
        //一共搜索到多少條記錄
        System.out.println("=====count=====" + topdocs.totalHits);
        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topdocs.scoreDocs;

        for(ScoreDoc scoreDoc : scoreDocs){
            //獲取docID
            int docID = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docID);
            //get域名可以取出值 打印
            System.out.println("fileName:" + document.get("fileName"));
            System.out.println("fileSize:" + document.get("fileSize"));
            System.out.println("============================================================");
        }
    }

QueryParser:

根據(jù)域名進(jìn)行搜索,可以設(shè)置默認(rèn)搜索域,推薦使用. (只能從文本中進(jìn)行搜索)
通過QueryParser也可以創(chuàng)建Query,QueryParser提供一個(gè)Parse方法,此方法可以直接根據(jù)查詢語法來查詢。Query對(duì)象執(zhí)行的查詢語法可通過System.out.println(query);查詢,需要使用到分析器。建議創(chuàng)建索引時(shí)使用的分析器和查詢索引時(shí)使用的分析器要一致。
1 , 需要加入queryParser依賴的jar包。
\lib\lucene-queryparser-4.10.3.jar
2,實(shí)現(xiàn)

private String searchField = "fileName";
    private String searchWord = "1.create web page.txt";

    @Test
    public void testIndexSearch() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();

        //指定索引和文檔的目錄
        Directory dir  = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
        //索引和文檔的讀取對(duì)象
        DirectoryReader indexReader = IndexReader.open(dir);
        //創(chuàng)建索引的搜索對(duì)象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        /**
         * 默認(rèn)搜索域作用:如果搜索語法中指定域名從指定域中搜索,如果搜索時(shí)只寫了查詢關(guān)鍵字,則從默認(rèn)搜索域中進(jìn)行搜索
         * 第一個(gè)參數(shù):默認(rèn)搜索域,
         * 第二個(gè)參數(shù):分詞器
         */
        QueryParser queryParser = new QueryParser("fileContent" , analyzer);
//        Query query = queryParser.parse("apache");//從默認(rèn)域搜索
        Query query = queryParser.parse(searchField+":"+searchWord);//從指定域搜索
        /**
         * 搜索:
         * 第一個(gè)參數(shù)為查詢語句對(duì)象
         * 第二個(gè)參數(shù):指定顯示多少條
         */
        TopDocs topDocs = indexSearcher.search(query, 10);
        //一共搜索到多少條記錄
        System.out.println("=====count======"+topDocs.totalHits);
        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;

        for (ScoreDoc scoreDoc : scoreDocs){
            //獲取docId
            int docId = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docId);
            System.out.println("fileName="+document.get("fileName"));
            System.out.println("fileSize="+document.get("fileSize"));
            System.out.println("=====================================");
        }
    }

NumericRangeQuery:

從數(shù)值范圍進(jìn)行搜索

@Test
    public void testNumericRangeQuery() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();

        //指定索引和文檔的目錄
        FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
        IndexReader indexReader = IndexReader.open(dir);
        //創(chuàng)建索引的搜索對(duì)象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //根據(jù)數(shù)字范圍查詢
        //查詢文件大小,大于100 小于1000的文章
        /**
         * 第一個(gè)參數(shù):域名
         * 第二個(gè)參數(shù):最小值,
         * 第三個(gè)參數(shù):最大值,
         * 第四個(gè)參數(shù):是否包含最小值,
         * 第五個(gè)參數(shù):是否包含最大值
         */

        NumericRangeQuery<Long> query = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);
        //搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
        TopDocs topdocs = indexSearcher.search(query, 10);

        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topdocs.scoreDocs;

        for(ScoreDoc scoreDoc : scoreDocs){
            //獲取docID
            int docID = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docID);
            //get域名可以取出值 打印
            System.out.println("fileName:" + document.get("fileName"));
            System.out.println("fileSize:" + document.get("fileSize"));
            System.out.println("============================================================");
        }
    }

BooleanQuery:

  • 組合查詢,可以設(shè)置組合條件,not and or.從多個(gè)域中進(jìn)行查詢
  • must相當(dāng)于and關(guān)鍵字,是并且的意思
  • should,相當(dāng)于or關(guān)鍵字或者的意思
  • must_not相當(dāng)于not關(guān)鍵字, 非的意思
  • 注意:單獨(dú)使用must_not 或者 獨(dú)自使用must_not沒有任何意義
    @Test
    public void testBooleanQuery() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();

        //指定索引和文檔的目錄
        FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
        IndexReader indexReader = IndexReader.open(dir);
        //創(chuàng)建索引的搜索對(duì)象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //布爾查詢,就是可以根據(jù)多個(gè)條件組合進(jìn)行查詢
        //文件名稱包含apache的,并且文件大小大于等于100 小于等于1000字節(jié)的文章
        BooleanQuery query = new BooleanQuery();

        //創(chuàng)建詞元:就是詞,
        Term t = new Term("fileName" , "apache");
        //使用TermQuery查詢,根據(jù)term對(duì)象進(jìn)行查詢
        TermQuery termQuery = new TermQuery(t);

        //根據(jù)數(shù)字范圍查詢
        //查詢文件大小,大于100 小于1000的文章
        NumericRangeQuery<Long> numQuery = NumericRangeQuery.newLongRange("fileSize", 100L, 1000L, true, true);

        //Occur是邏輯條件
        //must相當(dāng)于and關(guān)鍵字,是并且的意思
        //should,相當(dāng)于or關(guān)鍵字或者的意思
        //must_not相當(dāng)于not關(guān)鍵字, 非的意思
        //注意:單獨(dú)使用must_not  或者 獨(dú)自使用must_not沒有任何意義
        query.add(termQuery , BooleanClause.Occur.MUST);
        query.add(numQuery , BooleanClause.Occur.MUST);

        TopDocs topdocs = indexSearcher.search(query, 10);

        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topdocs.scoreDocs;

        for(ScoreDoc scoreDoc : scoreDocs){
            //獲取docID
            int docID = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docID);
            //get域名可以取出值 打印
            System.out.println("fileName:" + document.get("fileName"));
            System.out.println("fileSize:" + document.get("fileSize"));
            System.out.println("============================================================");
        }

    }

MatchAllDocsQuery:

查詢出所有文檔

@Test
    public void testMathAllQuery() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和所有時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();
        
        //查詢所有文檔
        MatchAllDocsQuery query = new MatchAllDocsQuery();
        
        //指定索引和文檔的目錄
        Directory dir = FSDirectory.open(new File("E:\\dic"));
        //索引和文檔的讀取對(duì)象
        IndexReader indexReader = IndexReader.open(dir);
        //創(chuàng)建索引的搜索對(duì)象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
        TopDocs topdocs = indexSearcher.search(query, 5);
        //一共搜索到多少條記錄
        System.out.println("=====count=====" + topdocs.totalHits);
        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topdocs.scoreDocs;
        
        for(ScoreDoc scoreDoc : scoreDocs){
            //獲取docID
            int docID = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docID);
            //get域名可以取出值 打印
            System.out.println("fileName:" + document.get("fileName"));
            System.out.println("fileSize:" + document.get("fileSize"));
            System.out.println("============================================================");
        }
    }

MultiFieldQueryParser:

可以從多個(gè)域中進(jìn)行查詢,只有這些域中有關(guān)鍵詞的存在就查詢出來.

@Test
    public void testMultiFieldQueryParser() throws Exception{
        //創(chuàng)建分詞器(創(chuàng)建索引和搜索時(shí)所用的分詞器必須一致)
        Analyzer analyzer = new IKAnalyzer();

        //指定索引和文檔的目錄
        FSDirectory dir = FSDirectory.open(new File("D:\\BaiduNetdiskDownload\\lucene_day01\\tmp"));
        IndexReader indexReader = IndexReader.open(dir);
        //創(chuàng)建索引的搜索對(duì)象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        String[] fields = {"fileName" , "fileContext"};
        //從文件名稱和文件內(nèi)容中查詢,只有含有apache的就查出來
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields , analyzer);
        //輸入需要搜索的關(guān)鍵字
        Query query = queryParser.parse("apache");
        //搜索:第一個(gè)參數(shù)為查詢語句對(duì)象, 第二個(gè)參數(shù):指定顯示多少條
        TopDocs topdocs = indexSearcher.search(query, 10);

        //從搜索結(jié)果對(duì)象中獲取結(jié)果集
        ScoreDoc[] scoreDocs = topdocs.scoreDocs;

        for(ScoreDoc scoreDoc : scoreDocs){
            //獲取docID
            int docID = scoreDoc.doc;
            //通過文檔ID從硬盤中讀取出對(duì)應(yīng)的文檔
            Document document = indexReader.document(docID);
            //get域名可以取出值 打印
            System.out.println("fileName:" + document.get("fileName"));
            System.out.println("fileSize:" + document.get("fileSize"));
            System.out.println("============================================================");
        }
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容