基于Lucene的全文檢索系統的實現與應用

文章目錄

  • 一、概念
  • 二、引入案例
    • 1、數據庫搜索
    • 2、數據分類
    • 3、非結構化數據查詢方法
      • 1) 順序掃描法(Serial Scanning)
      • 2)全文檢索(Full-text Search)
    • 4、如何實現全文檢索
  • 三、Lucene實現全文檢索的流程
    • 1、索引和搜索流程圖
    • 2、創建索引
      • 1)獲取原始文檔
      • 2)創建文檔對象
      • 3)分析文檔
      • 4)創建索引
    • 3、查詢索引
      • 1)創建查詢
      • 2)執行查詢
      • 3)渲染結果
  • 四、配置開發環境
    • 1、Lucene下載
    • 2、需要使用的jar包
  • 五、功能實現
    • 1、創建索引庫
      • 1)實現步驟
      • 2)Field說明
      • 3)代碼實現
      • 4)使用Luke工具查看索引文件
    • 2、查詢索引
      • 1)實現步驟
      • 2)IndexSearcher搜索方法
      • 3)代碼實現
    • 3、支持中文分詞
      • 1)分析器(Analyzer)的執行過程
      • 2)選擇中文分析器
      • 3)Analyzer使用時機
    • 3、維護索引庫
      • 1)索引庫刪除
      • 2)索引庫修改
  • 六、Lucene索引庫查詢(重點)
    • 1、使用query的子類查詢
    • 2、使用queryparser查詢
      • 1)查詢語法
      • 2)使用

一、概念

Lucene是一個開源的全文搜索引擎庫,用于實現文本索引和搜索功能。它提供了強大的搜索和排序功能,可以用于構建各種類型的搜索應用程序,如網站搜索引擎、文檔管理系統等。Lucene支持多種編程語言,并且具有高性能和可擴展性。它是許多其他搜索引擎和文本處理工具的基礎。

二、引入案例

我們要實現一個文件的搜索功能,通過關鍵字搜索文件,凡是文件名或文件內容包括該關鍵字的文件都需要找出來,還可以根據中文詞語進行查詢,并且需要支持多個條件查詢,應該怎么做?分析一波~

1、數據庫搜索

有沒有想過,為什么數據庫實現搜索很容易?

一般都是使用sql語句進行查詢,而且能很快的得到查詢結果。因為數據庫中的數據存儲是有規律的,有行有列而且數據格式、數據長度都是固定的。

2、數據分類

我們生活中的數據總體分為兩種:結構化數據和非結構化數據。

  • 結構化數據:指具有固定格式或有限長度的數據,如數據庫,元數據等。
  • 非結構化數據:指不定長或無固定格式的數據,如郵件,word文檔等磁盤上的文件。

3、非結構化數據查詢方法

那么非結構化數據查詢,怎么實現?

1) 順序掃描法(Serial Scanning)

所謂順序掃描,比如要找內容包含某一個字符串的文件,就是一個文檔一個文檔的看,對于每一個文檔,從頭看到尾,如果此文檔包含此字符串,則此文檔為我們要找的文件,接著看下一個文件,直到掃描完所有的文件。如利用windows的搜索也可以搜索文件內容,只是相當的慢。

2)全文檢索(Full-text Search)

將非結構化數據中的一部分信息提取出來,重新組織,使其變得有一定結構,然后對此有一定結構的數據進行搜索,從而達到搜索相對較快的目的。這部分從非結構化數據中提取出的然后重新組織的信息,我們稱之索引。

例如:字典。字典的拼音表和部首檢字表就相當于字典的索引,對每一個字的解釋是非結構化的,如果字典沒有音節表和部首檢字表,在茫茫辭海中找一個字只能順序掃描。然而字的某些信息可以提取出來進行結構化處理,比如讀音,就比較結構化,分聲母和韻母,分別只有幾種可以一一列舉,于是將讀音拿出來按一定的順序排列,每一項讀音都指向此字的詳細解釋的頁數。我們搜索時按結構化的拼音搜到讀音,然后按其指向的頁數,便可找到我們的非結構化數據——也即對字的解釋。

這種先建立索引,再對索引進行搜索的過程就叫全文檢索。

雖然創建索引的過程也是非常耗時的,但是索引一旦創建就可以多次使用,全文檢索主要處理的是查詢,所以耗時間創建索引是值得的。

4、如何實現全文檢索

對于數據量大、數據結構不固定的數據可采用全文檢索方式搜索,比如百度、Google等搜索引擎、論壇站內搜索、電商網站站內搜索等。

可以使用Lucene實現全文檢索。Lucene是apache下的一個開放源代碼的全文檢索引擎工具包。提供了完整的查詢引擎和索引引擎,部分文本分析引擎。Lucene的目的是為軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能。

三、Lucene實現全文檢索的流程

1、索引和搜索流程圖

在這里插入圖片描述
1、綠色:表示索引過程,對要搜索的原始內容進行索引構建一個索引庫
索引過程:確定原始內容,即要搜索的內容,采集文檔,創建文檔,分析文檔,索引文檔

2、紅色表示搜索過程,從索引庫中搜索內容
搜索過程:用戶通過搜索界面,創建查詢執行搜索,從索引庫搜索渲染搜索結果

2、創建索引

對文檔索引的過程,將用戶要搜索的文檔內容進行索引,索引存儲在索引庫(index)中。
這里我們要搜索的文檔是磁盤上的文本文件,根據案例描述:凡是文件名或文件內容包括關鍵字的文件都要找出來,這里要對文件名和文件內容創建索引。

1)獲取原始文檔

原始文檔是指要索引和搜索的內容。原始內容包括互聯網上的網頁、數據庫中的數據、磁盤上的文件等。

本案例中的原始內容就是磁盤上的文件,如下圖:
在這里插入圖片描述

從互聯網上、數據庫、文件系統中等獲取需要搜索的原始信息,這個過程就是信息采集,信息采集的目的是為了對原始內容進行索引。

在Internet上采集信息的軟件通常稱為爬蟲或蜘蛛,也稱為網絡機器人,爬蟲訪問互聯網上的每一個網頁,將獲取到的網頁內容存儲起來。

Lucene不提供信息采集的類庫,需要自己編寫一個爬蟲程序實現信息采集,也可以通過一些開源軟件實現信息采集,如下:

  • Nutch(http://lucene.apache.org/nutch), Nutch是apache的一個子項目,包括大規模爬蟲工具,能夠抓取和分辨web網站數據。

  • jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數據。

  • heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix 是一個由 java 開發的、開源的網絡爬蟲,用戶可以使用它來從網上抓取想要的資源。其最出色之處在于它良好的可擴展性,方便用戶實現自己的抓取邏輯。

本案例我們要獲取磁盤上文件的內容,可以通過文件流來讀取文本文件的內容,對于pdf、doc、xls等文件可通過第三方提供的解析工具讀取文件內容,比如Apache POI讀取doc和xls的文件內容。

2)創建文檔對象

獲取原始內容的目的是為了索引,在索引前需要將原始內容創建成文檔(Document),文檔中包括一個一個的域(Field),域中存儲內容。
這里我們可以將磁盤上的一個文件當成一個document,Document中包括一些Field(file_name文件名稱、file_path文件路徑、file_size文件大小、file_content文件內容),如下圖:
在這里插入圖片描述
注:每個Document可以有多個Field,不同的Document可以有不同的Field,同一個Document可以有相同的Field(域名和域值都相同)
每個文檔都有一個唯一的編號,就是文檔id。

3)分析文檔

將原始內容創建為包含域(Field)的文檔(document),需要再對域中的內容進行分析,分析的過程是經過對原始文檔提取單詞、將字母轉為小寫、去除標點符號、去除停用詞等過程生成最終的語匯單元,可以將語匯單元理解為一個一個的單詞。

原文檔內容:

Lucene is a Java full-text search engine. Lucene is not a complete
application, but rather a code library and API that can easily be used
to add search capabilities to applications.

分析后得到的語匯單元:

lucene、java、full、search、engine。。。。

每個單詞叫做一個Term,不同的域中拆分出來的相同的單詞是不同的term。term中包含兩部分一部分是文檔的域名,另一部分是單詞的內容。

例如:文件名中包含apache和文件內容中包含的apache是不同的term。

4)創建索引

對所有文檔分析得出的語匯單元進行索引,索引的目的是為了搜索,最終要實現只搜索被索引的語匯單元從而找到Document(文檔)。
在這里插入圖片描述一個索引可能對應多個文檔

注:一個索引可能對應多個文檔,創建索引是對語匯單元索引,通過詞語找文檔,這種索引的結構叫倒排索引結構。

傳統方法是根據文件找到該文件的內容,在文件內容中匹配搜索關鍵字,這種方法是順序掃描方法,數據量大、搜索慢。

倒排索引結構是根據內容(詞語)找文檔,如下圖:
在這里插入圖片描述
倒排索引結構也叫反向索引結構,包括索引和文檔兩部分,索引即詞匯表,它的規模較小,而文檔集合較大。

3、查詢索引

1)創建查詢

用戶輸入查詢關鍵字執行搜索之前需要先構建一個查詢對象,查詢對象中可以指定查詢要搜索的Field文檔域、查詢關鍵字等,查詢對象會生成具體的查詢語法。
例如:語法 “fileName:lucene”表示要搜索Field域的內容為“lucene”的文檔

2)執行查詢

搜索索引過程:根據查詢語法在倒排索引詞典表中分別找出對應搜索詞的索引,從而找到索引所鏈接的文檔鏈表。
比如搜索語法為“fileName:lucene”表示搜索出fileName域中包含Lucene的文檔。
搜索過程就是在索引上查找域為fileName,并且關鍵字為Lucene的term,并根據term找到文檔id列表。

3)渲染結果

全文檢索系統提供用戶搜索的界面供用戶提交搜索的關鍵字,搜索完成展示搜索結果。

以一個友好的界面將查詢結果展示給用戶,用戶根據搜索結果找自己想要的信息,為了幫助用戶很快找到自己的結果,提供了很多展示的效果,比如搜索結果中將關鍵字高亮顯示,百度提供的快照等。
在這里插入圖片描述

四、配置開發環境

1、Lucene下載

官方網站:http://lucene.apache.org/

Lucene是開發全文檢索功能的工具包,從官方網站下載Lucene4.10.3,并解壓。

2、需要使用的jar包

Lucene包:

  • lucene-core-4.10.3.jar
  • lucene-analyzers-common-4.10.3.jar
  • lucene-queryparser-4.10.3.jar

其它包:

  • commons-io-2.4.jar
  • junit-4.9.jar

五、功能實現

1、創建索引庫

1)實現步驟

  • 第一步:創建一個java工程,新建一個文件夾lib,并導入jar包,添加到工作路徑去。
  • 第二步:新建一個測試類,添加測試方法
  • 第三步:創建一個indexwriter對象。
    1)指定索引庫的存放位置Directory對象
    2)指定一個分析器,對文檔內容進行分析。
  • 第四步:創建document對象。
  • 第五步:創建field對象,將field添加到document對象中。
  • 第六步:使用indexwriter對象將document對象寫入索引庫,此過程進行索引創建。并將索引和document對象寫入索引庫。
  • 第七步:關閉IndexWriter對象。

2)Field說明

Field域屬性:

  • 是否分析:是否對域的內容進行分詞處理。前提是我們要對域的內容進行查詢。
  • 是否索引:將Field分析后的詞或整個Field值進行索引,只有索引方可搜索到。
    比如:商品名稱、商品簡介分析后進行索引,訂單號、身份證號不用分析但也要索引,這些將來都要作為查詢條件。
  • 是否存儲:將Field值存儲在文檔中,存儲在文檔中的Field才可以從Document中獲取
    比如:商品名稱、訂單號,凡是將來要從Document中獲取的Field都要存儲。
  • 是否存儲的標準:是否要將內容展示給用戶

Field類:
在這里插入圖片描述

3)代碼實現

import java.io.File;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StoredField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;public class FirstLucene {@Testpublic void testIndex() throws Exception{//創建一個indexwriter對象Directory directory=FSDirectory.open(new File("F:\\time"));//索引庫Analyzer analyzer=new StandardAnalyzer();//官方分析器IndexWriterConfig config=new IndexWriterConfig(Version.LATEST, analyzer);IndexWriter iw=new IndexWriter(directory, config);//創建field對象,并添加到docement對象中File f=new File("F:\\source");File[] listFiles = f.listFiles();for (File file : listFiles) {//創建docement對象Document document=new Document();String file_name=file.getName();Field fileNameField=new TextField("fileName",file_name,Store.YES);long file_size=FileUtils.sizeOf(file);Field fileSizeField=new LongField("fileSize",file_size, Store.YES);String file_path=file.getPath();Field filePathField=new StoredField("filePath",file_path);String file_content=FileUtils.readFileToString(file);Field fileContentField=new TextField("fileContent",file_content,Store.YES);document.add(fileNameField);document.add(fileSizeField);document.add(filePathField);document.add(fileContentField);//使用indexwriter對象將document對象寫入索引庫iw.addDocument(document);}//關閉IndexWriter對象iw.close();}
}

4)使用Luke工具查看索引文件

啟動后,填入我們的索引路徑即可
在這里插入圖片描述

2、查詢索引

1)實現步驟

  • 第一步:創建一個Directory對象,也就是索引庫存放的位置。
  • 第二步:創建一個indexReader對象,需要指定Directory對象。
  • 第三步:創建一個indexsearcher對象,需要指定IndexReader對象
  • 第四步:創建一個TermQuery對象,指定查詢的域和查詢的關鍵詞。
  • 第五步:執行查詢。
  • 第六步:返回查詢結果。遍歷查詢結果并輸出。
  • 第七步:關閉IndexReader對象

2)IndexSearcher搜索方法

在這里插入圖片描述

3)代碼實現

//搜索索引@Testpublic void testSearch() throws Exception{//創建一個Directory對象,也就是索引庫存放的位置。Directory directory=FSDirectory.open(new File("F:\\time"));//創建一個indexReader對象,需要指定Directory對象。IndexReader ir=DirectoryReader.open(directory);//創建一個indexsearcher對象,需要指定IndexReader對象IndexSearcher indexsearcher=new IndexSearcher(ir);//創建一個TermQuery對象,指定查詢的域和查詢的關鍵詞。Query query=new TermQuery(new Term("fileName","notice.txt"));//執行查詢。TopDocs topDocs = indexsearcher.search(query, 2);//返回查詢結果。遍歷查詢結果并輸出。ScoreDoc[] scoreDocs = topDocs.scoreDocs;//文檔idfor (ScoreDoc scoreDoc : scoreDocs) {int doc = scoreDoc.doc;Document document = indexsearcher.doc(doc);//獲取文檔String fileName = document.get("fileName");System.out.println(fileName);String fileContent = document.get("fileContent");System.out.println(fileContent);String fileSize= document.get("fileSize");System.out.println(fileSize);String filePath = document.get("filePath");System.out.println(filePath);System.out.println("-----------------------------");}//關閉IndexReader對象ir.close();}

3、支持中文分詞

1)分析器(Analyzer)的執行過程

如下圖是語匯單元的生成過程:
在這里插入圖片描述
從一個Reader字符流開始,創建一個基于Reader的Tokenizer分詞器,經過三個TokenFilter生成語匯單元Tokens。

要看分析器的分析效果,只需要看Tokenstream中的內容就可以了。每個分析器都有一個方法tokenStream,返回一個tokenStream對象。

2)選擇中文分析器

Lucene自帶中文分詞器:

  • StandardAnalyzer:單字分詞,按照中文一個字一個字地進行分詞。如:“我愛中國”,效果:“我”、“愛”、“中”、“國”。
  • CJKAnalyzer:二分法分詞,按兩個字進行切分。如:“我是中國人”,效果:“我是”、“是中”、“中國”“國人”。
  • SmartChineseAnalyzer:對中文支持較好,但擴展性差,擴展詞庫,禁用詞庫和同義詞庫等不好處理

第三方中文分析器

IK-analyzer: 最新版在https://code.google.com/p/ik-analyzer/上,支持Lucene 4.10從2006年12月推出1.0版開始, IKAnalyzer已經推出了4個大版本。最初,它是以開源項目Luence為應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。從3.0版本開 始,IK發展為面向Java的公用分詞組件,獨立于Lucene項目,同時提供了對Lucene的默認優化實現。在2012版本中,IK實現了簡單的分詞 歧義排除算法,標志著IK分詞器從單純的詞典分詞向模擬語義分詞衍化。 但是也就是2012年12月后沒有在更新。

IKAnalyzer使用
在這里插入圖片描述
第一步:把IKAnalyzer2012FF_u1.jar包添加到工程中
第二步:把配置文件和擴展詞典和停用詞詞典添加到classpath下
在這里插入圖片描述
測試代碼

	@Testpublic void testTokenStream() throws Exception {// 創建一個標準分析器對象Analyzer analyzer = new IKAnalyzer();// 獲得tokenStream對象// 第一個參數:域名,可以隨便給一個// 第二個參數:要分析的文本內容TokenStream tokenStream = analyzer.tokenStream("test","高富帥可以用二維表結構來邏輯表達實現的數據");// 添加一個引用,可以獲得每個關鍵詞CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);// 添加一個偏移量的引用,記錄了關鍵詞的開始位置以及結束位置OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);// 將指針調整到列表的頭部tokenStream.reset();// 遍歷關鍵詞列表,通過incrementToken方法判斷列表是否結束while (tokenStream.incrementToken()) {// 關鍵詞的起始位置System.out.println("start->" + offsetAttribute.startOffset());// 取關鍵詞System.out.println(charTermAttribute);// 結束位置System.out.println("end->" + offsetAttribute.endOffset());}tokenStream.close();}

在這里插入圖片描述
ext.dic里面保留要的字段
stopword.dic保留不要的字段

3)Analyzer使用時機

輸入關鍵字進行搜索,當需要讓該關鍵字與文檔域內容所包含的詞進行匹配時需要對文檔域內容進行分析,需要經過Analyzer分析器處理生成語匯單元(Token)。分析器分析的對象是文檔中的Field域。當Field的屬性tokenized(是否分詞)為true時會對Field值進行分析,如下圖:
在這里插入圖片描述
對于一些Field可以不用分析:
1、不作為查詢條件的內容,比如文件路徑
2、不是匹配內容中的詞而匹配Field的整體內容,比如訂單號、身份證號等。

注意:搜索使用的分析器要和索引使用的分析器一致。

3、維護索引庫

新建一個class,用于測試

1)索引庫刪除

刪除全部

package com.it.lucene;import java.io.File;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;public class LuceneManager {public IndexWriter getIndexWriter() throws Exception{//創建一個indexwriter對象Directory directory=FSDirectory.open(new File("F:\\time"));//索引庫Analyzer analyzer=new StandardAnalyzer();//官方分析器IndexWriterConfig config=new IndexWriterConfig(Version.LATEST, analyzer);return new IndexWriter(directory, config);}//全刪除@Testpublic void testAllDelete() throws Exception{IndexWriter indexWriter=getIndexWriter();indexWriter.deleteAll();indexWriter.close();}
}

指定查詢條件刪除

	//根據條件刪除@Testpublic void testDelete() throws Exception{IndexWriter indexWriter=getIndexWriter();Query query=new TermQuery(new Term("fileName","notice.txt"));indexWriter.deleteDocuments(query);indexWriter.close();}

2)索引庫修改

原理就是先刪除后添加。

	//修改@Testpublic void testUpdate() throws Exception{IndexWriter indexWriter=getIndexWriter();Document doc=new Document();doc.add(new TextField("fileN","測試文件名",Store.YES));indexWriter.updateDocument(new Term("fileName","notice"),doc,new IKAnalyzer());indexWriter.close();}

六、Lucene索引庫查詢(重點)

對要搜索的信息創建Query查詢對象,Lucene會根據Query查詢對象生成最終的查詢語法,類似關系數據庫Sql語法一樣Lucene也有自己的查詢語法,比如:“name:lucene”表示查詢Field的name為“lucene”的文檔信息。

可通過兩種方法創建查詢對象:

1)使用Lucene提供Query子類
Query是一個抽象類,lucene提供了很多查詢對象,比如TermQuery項精確查詢,NumericRangeQuery數字范圍查詢等。
如下代碼:

Query query = new TermQuery(new Term("name", "lucene"));

2)使用QueryParse解析查詢表達式
QueryParse會將用戶輸入的查詢表達式解析成Query對象實例。
如下代碼:

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

1、使用query的子類查詢

使用MatchAllDocsQuery查詢索引目錄中的所有文檔

public IndexSearcher getIndexSearcher() throws Exception{//創建一個Directory對象,也就是索引庫存放的位置。Directory directory=FSDirectory.open(new File("F:\\time"));//創建一個indexReader對象,需要指定Directory對象。IndexReader ir=DirectoryReader.open(directory);//創建一個indexsearcher對象,需要指定IndexReader對象return new IndexSearcher(ir);
}//執行查詢結果
public static void printResult(IndexSearcher indexsearcher,Query query) throws Exception{  //執行查詢。TopDocs topDocs = indexsearcher.search(query, 2);//返回查詢結果。遍歷查詢結果并輸出。ScoreDoc[] scoreDocs = topDocs.scoreDocs;//文檔idfor (ScoreDoc scoreDoc : scoreDocs) {int doc = scoreDoc.doc;Document document = indexsearcher.doc(doc);//獲取文檔String fileName = document.get("fileName");System.out.println(fileName);String fileContent = document.get("fileContent");System.out.println(fileContent);String fileSize= document.get("fileSize");System.out.println(fileSize);String filePath = document.get("filePath");System.out.println(filePath);System.out.println("-----------------------------");}
} 
//查詢所有
@Test
public void testMatchAllDocsQuery() throws Exception{IndexSearcher indexSearcher=getIndexSearcher();Query query=new MatchAllDocsQuery();printResult(indexSearcher,query);indexSearcher.getIndexReader().close();
}

TermQuery:指定要查詢的域和要查詢的關鍵詞。
TermQuery不使用分析器,所以建議匹配不分詞的Field域查詢,比如訂單號、分類ID號等。

//使用Termquery查詢
@Test
public void testTermQuery() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();//創建查詢對象Query query = new TermQuery(new Term("fileName", "notice"));//執行查詢TopDocs topDocs = indexSearcher.search(query, 10);//共查詢到的document個數System.out.println("查詢結果總數量:" + topDocs.totalHits);
}

NumericRangeQuery:可以根據數值范圍查詢

//根據數值范圍查詢
@Test
public void testNumericRangeQuery() throws Exception{IndexSearcher indexSearcher=getIndexSearcher();Query query=NumericRangeQuery.newLongRange("fileSize", 1L, 20000L, true, true);printResult(indexSearcher,query);indexSearcher.getIndexReader().close();
}

BooleanQuery:可以組合查詢條件

//組合條件查詢
@Test
public void testBooleanQuery() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();//創建一個布爾查詢對象BooleanQuery query = new BooleanQuery();//創建第一個查詢條件Query query1 = new TermQuery(new Term("fileName", "notice"));Query query2 = new TermQuery(new Term("fileContent", "has"));//組合查詢條件query.add(query1, Occur.SHOULD);query.add(query2, Occur.SHOULD);//執行查詢printResult(indexSearcher,query);
}

2、使用queryparser查詢

通過QueryParser也可以創建Query,QueryParser提供一個Parse方法,此方法可以直接根據查詢語法來查詢。

注:需要使用到分析器的話,建議創建索引和查詢索引使用的分析器要一致。

1)查詢語法

1、基礎的查詢語法,關鍵詞查詢:
域名+“:”+搜索的關鍵字
例如:content:java

2、范圍查詢
域名+“:”+[最小值 TO 最大值]
例如:size:[1 TO 1000]
范圍查詢在lucene中支持數值類型,不支持字符串類型。在solr中支持字符串類型。

3、組合條件查詢

  • 寫法1:
    Occur.MUST 查詢條件必須滿足,相當于and:+
    Occur.SHOULD 查詢條件可選,相當于or:空
    Occur.MUST_NOT 查詢條件不能滿足,相當于not非:-

1)+條件1 +條件2:兩個條件之間是并且的關系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

寫法2:

  • 條件1 AND 條件2
  • 條件1 OR 條件2
  • 條件1 NOT 條件2

2)使用

QueryParser

//條件解析的對象查詢      @Test
public void testQueryParser() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();//創建queryparser對象//第一個參數默認搜索的域//第二個參數就是分析器對象QueryParser queryParser = new QueryParser("fileName",new IKAnalyzer());//*:* 域:值Query query = queryParser.parse("notice");//執行查詢printResult(indexSearcher,query);
}

MultiFieldQueryParser:可以指定多個默認搜索域

//條件解析的對象查詢 多個默認域
@Test
public void testMultiFiledQueryParser() throws Exception {IndexSearcher indexSearcher = getIndexSearcher();//可以指定默認搜索的域是多個String[] fields = {"fileName", "fileContent"};//創建一個MulitFiledQueryParser對象MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());Query query = queryParser.parse("java AND apache");System.out.println(query);//執行查詢printResult(indexSearcher,query);}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209323.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209323.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209323.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

模板與泛型編程

函數模板 顯示實例化 區別定義與聲明 T是模板形參 int是模板實參 inpunt是函數形參 3是函數實參 顯示實例化 模板必須實例化可見 翻譯單元一處定義原則 與內聯函數異同 引入原因:函數模板是為了編譯器兩個階段的處理 內聯函數是為了能在編譯期展開 模板實參的類…

Android Kotlin語言下的文件存儲

目錄 將數據存儲到文件中 創建文件和保存數據 讀取文件 SharedPreferences存儲 存儲數據到SharedPreferences中 Context類中的getSharedPreferences()方法 Activity類中的getPreferences()方法 從SharedPreferences中讀取數據 SQLite數據庫存儲 創建數據庫 調用數據…

Java導出word

原文地址 傳入的值不能為null,否則會報錯,IXDocReport 有自己的判null規則,比較麻煩,建議代碼直接把null替換成"" public void exportWord1(WeeklyMeetDataDto dto, HttpServletResponse response) {ServletOutputStream downLoad…

Ignis - Interactive Fire System

Ignis - 點火、蔓延、熄滅、定制! 全方位火焰系統。 這個插件在21年的項目中使用過很好用值使用概述 想玩火嗎?如果想的話,那么Ignis就是你的最佳工具。有了Ignis,你可以把任何物體、植被或帶皮帶骨的網狀物轉換為可燃物體,它就會自動著火。然后,火焰可以蔓延,點燃其他物…

Java 一對多

前言 Internet 協議集支持一個無連接的傳輸協議,該協議稱為用戶數據報協議(UDP,User Datagram Protocol)。UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。 此代碼就是基于UDP協議編寫。 通常把一對多的…

【docker 】centOS 安裝docker

官網 docker官網 github源碼 卸載舊版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安裝軟件包 yum install -y yum-utils \device-mapper-persistent-data…

【優選算法系列】【專題二滑動窗口】第四節.30. 串聯所有單詞的子串和76. 最小覆蓋子串

文章目錄 前言一、串聯所有單詞的子串 1.1 題目描述 1.2 題目解析 1.2.1 算法原理 1.2.2 代碼編寫 1.2.3 題目總結二、最小覆蓋子串 2.1 題目描述 2.2 題目解析 2.2.1 算法原理 2.2.2 代碼編寫 …

【Docker】進階之路:(四)操作容器

【Docker】進階之路:(四)Docker容器 容器的生命周期創建容器docker createdocker run 管理容器查看運行的容器:查看所有容器: 啟動與終止啟動容器終止容器 進入容器docker attachdocker exec 導出和導入導出導入 容器的…

淺談5G基站節能及數字化管理解決方案的設計與應用-安科瑞 蔣靜

截至2023年10月,我國5G基站總數達321.5萬個,占全國通信基站總數的28.1%。然而,隨著5G基站數量的快速增長,基站的能耗問題也逐漸日益凸顯,基站的用電給運營商帶來了巨大的電費開支壓力,降低5G基站的能耗成為…

actitivi自定義屬性(二)

聲明:此處activiti版本為6.0 此文章介紹后端自定義屬性解析,前端添加自定義屬性方法連接:activiti自定義屬性(一)_ruoyi activiti自定義標題-CSDN博客 1、涉及到的類如下: 簡介:DefaultXmlPar…

在 JavaScript 中導入和導出 Excel XLSX 文件:SpreadJS

在 JavaScript 中導入和導出 Excel XLSX 文件 2023 年 12 月 5 日 使用 MESCIUS 的 SpreadJS 將完整的 JavaScript 電子表格添加到您的企業應用程序中。 SpreadJS 是一個完整的企業 JavaScript 電子表格解決方案,用于創建財務報告和儀表板、預算和預測模型、科學、工…

【華為OD】給定一個只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串

給定一個只包括 (,),{,},[,] 的字符串 s , 判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 示例 1 : 輸入:s="()" 輸出 : true 示例 2 :

圖的搜索(一):廣度優先搜索算法和深度優先搜索算法

圖的搜索(一):廣度優先搜索算法和深度優先搜索算法 本章主要記錄了圖的搜索算法,和可以解決圖的基本問題——最短路徑問題的算法。本章主要對圖搜索的相關算法進行了介紹:廣度優先搜索算法、深度優先搜索算法。 下一…

公網域名如何解析到內網IP服務器——快解析域名映射外網訪問

在本地搭建主機應用后,由于沒有公網IP或沒有公網路由權限,在需要發布互聯網時,就需要用到外網訪問內網的一些方案。由于內網IP在外網不能直接訪問,通常就用通過外網域名來訪問內網的方法。那么,公網域名如何解析到內網…

Tmux中使用Docker報錯 - 解決方案

問題 進入Tmux會話后,在其中使用Docker可能會出現如下報錯: Got permission denied while trying to connect to the Docker ……解決方案 退出tmux會話: tmux detach在tmux會話外部殺掉tmux進程: pkill -f tmux重新進入tmux&#xff1a…

權威認證!景聯文科技入選杭州市2023年第二批省級“專精特新”中小企業認定名單

為深入貫徹黨中央國務院和省委省政府培育專精特新的決策部署,10月7日,杭州市經濟和信息化委員會公示了2023年杭州“專精特新”企業名單(第二批)。 根據工業和信息化部《優質中小企業梯度培育管理暫行辦法》(工信部企業…

【Vue3+Ts項目】硅谷甄選 — 路由配置+登錄模塊+layout組件+路由鑒權

一、路由配置 項目一共需要4個一級路由:登錄(login)、主頁(home)、404、任意路由(重定向到404)。 1.1 安裝路由插件 pnpm install vue-router 1.2 創建路由組件 在src目錄下新建views文件…

Graphpad Prism10.1.0 安裝教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常專業強大的科研醫學生物數據處理繪圖軟件,它可以將科學圖形、綜合曲線擬合(非線性回歸)、可理解的統計數據、數據組織結合在一起,除了最基本的數據統計分析外,還能自動生成統…

Python:核心知識點整理大全8-筆記

目錄 ?編輯 4.5 元組 4.5.1 定義元組 dimensions.py 4.5.2 遍歷元組中的所有值 4.5.3 修改元組變量 4.6 設置代碼格式 4.6.1 格式設置指南 4.6.2 縮進 4.6.3 行長 4.6.4 空行 4.6.5 其他格式設置指南 4.7 小結 第5章 if語句 5.1 一個簡單示例 cars.py 5.2 條…

現代皮質沙發模型材質編輯

在線工具推薦: 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時,有幾種不同的風格&#xf…