Lucene--搜索

Lucene--搜索

一、創(chuàng)建查詢對象的方式

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

可通過兩種方法創(chuàng)建查詢對象:

  • 使用Lucene提供Query子類

Query是一個抽象類,lucene提供了很多查詢對象,比如TermQuery項(xiàng)精確查詢,NumericRangeQuery數(shù)字范圍查詢等。
如下代碼:

Query query = new TermQuery(new Term("name", "lucene"));
  • 使用QueryParse解析查詢表達(dá)式

QueryParser會將用戶輸入的查詢表達(dá)式解析成Query對象實(shí)例。
如下代碼:

QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
Query query = queryParser.parse("name:lucene");

二、通過Query子類搜索

2.1 TermQuery

TermQuery項(xiàng)查詢,TermQuery不使用分析器,搜索關(guān)鍵詞作為整體來匹配Field域中的詞進(jìn)行查詢,比如訂單號、分類ID號等。

private void doSearch(Query query) {
    IndexReader reader = null;
    try {
        // a) 指定索引庫目錄
        Directory indexdirectory = FSDirectory.open(new File(
                "E:\\11-index\\0720"));
        // b) 創(chuàng)建IndexReader對象
        reader = DirectoryReader.open(indexdirectory);
        // c) 創(chuàng)建IndexSearcher對象
        IndexSearcher searcher = new IndexSearcher(reader);
        // d) 通過IndexSearcher對象執(zhí)行查詢索引庫,返回TopDocs對象
        // 第一個參數(shù):查詢對象
        // 第二個參數(shù):最大的n條記錄
        TopDocs topDocs = searcher.search(query, 10);
        // e) 提取TopDocs對象中的文檔ID,如何找出對應(yīng)的文檔
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("總共查詢出的結(jié)果總數(shù)為:" + topDocs.totalHits);
        Document doc;
        for (ScoreDoc scoreDoc : scoreDocs) {
            // 文檔對象ID
            int docId = scoreDoc.doc;
            doc = searcher.doc(docId);
            // f) 輸出文檔內(nèi)容
            System.out.println(doc.get("filename"));
            System.out.println(doc.get("path"));
            System.out.println(doc.get("size"));
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

@Test
public void testTermQuery() throws Exception {
    // 1、 創(chuàng)建查詢(Query對象)
    Query query = new TermQuery(new Term("filename", "apache"));
    // 2、 執(zhí)行搜索
    doSearch(query);
}

2.2 NumericRangeQuery

NumericRangeQuery,指定數(shù)字范圍查詢.

@Test
public void testNumbericRangeQuery() throws Exception {
    // 創(chuàng)建查詢
    // 第一個參數(shù):域名
    // 第二個參數(shù):最小值
    // 第三個參數(shù):最大值
    // 第四個參數(shù):是否包含最小值
    // 第五個參數(shù):是否包含最大值
    Query query = NumericRangeQuery.newLongRange("size", 1l, 100l, true,true);
    // 2、 執(zhí)行搜索
    doSearch(query);
}

2.3 BooleanQuery

BooleanQuery,布爾查詢,實(shí)現(xiàn)組合條件查詢。

@Test
public void booleanQuery() throws Exception {
    BooleanQuery query = new BooleanQuery();
    Query query1 = new TermQuery(new Term("id", "3"));
    Query query2 = NumericRangeQuery.newFloatRange("price", 10f, 200f,
            true, true);

    //MUST:查詢條件必須滿足,相當(dāng)于AND
    //SHOULD:查詢條件可選,相當(dāng)于OR
    //MUST_NOT:查詢條件不能滿足,相當(dāng)于NOT非
    query.add(query1, Occur.MUST);
    query.add(query2, Occur.SHOULD);
    
    System.out.println(query);

    search(query);
}

組合關(guān)系代表的意思如下:

1、MUST和MUST表示“與”的關(guān)系,即“交集”。 
2、MUST和MUST_NOT前者包含后者不包含。 
3、MUST_NOT和MUST_NOT沒意義 
4、SHOULD與MUST表示MUST,SHOULD失去意義; 
5、SHOUlD與MUST_NOT相當(dāng)于MUST與MUST_NOT。 
6、SHOULD與SHOULD表示“或”的概念。

三、通過QueryParser搜索

通過QueryParser也可以創(chuàng)建Query,QueryParser提供一個Parse方法,此方法可以直接根據(jù)查詢語法來查詢。Query對象執(zhí)行的查詢語法可通過System.out.println(query);查詢。

3.1 QueryParser

代碼實(shí)現(xiàn):

@Test
public void testQueryParser() throws Exception {
    // 創(chuàng)建QueryParser
    // 第一個參數(shù):默認(rèn)域名
    // 第二個參數(shù):分詞器
    QueryParser queryParser = new QueryParser("name", new IKAnalyzer());
    // 指定查詢語法 ,如果不指定域,就搜索默認(rèn)的域
    Query query = queryParser.parse("lucene");
    System.out.println(query);
    // 2、 執(zhí)行搜索
    doSearch(query);
}

查詢語法:

1、基礎(chǔ)的查詢語法,關(guān)鍵詞查詢:

域名+“:”+搜索的關(guān)鍵字
例如:content:java

2、范圍查詢

域名+“:”+[最小值 TO 最大值]
例如:size:[1 TO 1000]
注意:QueryParser不支持對數(shù)字范圍的搜索,它支持字符串范圍。
數(shù)字范圍搜索建議使用NumericRangeQuery。

3、組合條件查詢

組合條件查詢.PNG
1)+條件1 +條件2:兩個條件之間是并且的關(guān)系and
例如:+filename:apache +content:apache

2)+條件1 條件2:必須滿足第一個條件,忽略第二個條件
例如:+filename:apache content:apache

3)條件1 條件2:兩個條件滿足其一即可。
例如:filename:apache content:apache

4)-條件1 條件2:必須不滿足條件1,要滿足條件2
例如:-filename:apache content:apache

第二種寫法:
條件1 AND 條件2
條件1 OR 條件2
條件1 NOT 條件2

3.2 MultiFieldQueryParser

通過MultiFieldQueryParser對多個域查詢。

@Test
public void testMultiFieldQueryParser() throws Exception {
    // 可以指定默認(rèn)搜索的域是多個
    String[] fields = { "name", "description" };
    // 創(chuàng)建一個MulitFiledQueryParser對象
    QueryParser parser = new MultiFieldQueryParser(fields, new IKAnalyzer());
    // 指定查詢語法 ,如果不指定域,就搜索默認(rèn)的域
    Query query = parser.parse("lucene");
    //等同于name:lucene OR description:lucene
    // Query query = parser.parse("name:lucene OR description:lucene");
    // 2、 執(zhí)行搜索
    doSearch(query);
}

四、TopDocs

Lucene搜索結(jié)果可通過TopDocs遍歷,TopDocs類提供了少量的屬性,如下:

topdocs屬性.PNG

注意:

  • Search方法需要指定匹配記錄數(shù)量n:indexSearcher.search(query, n)
  • TopDocs.totalHits:是匹配索引庫中所有記錄的數(shù)量
  • TopDocs.scoreDocs:匹配相關(guān)度高的前邊記錄數(shù)組,scoreDocs的長度小于等于search方法指定的參數(shù)n
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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