Lucene5多條件查詢


lucene是一個很強大的搜索工具,最近公司項目上用到,結合JAVA1234所講,對多條件查詢做出總結

先描述一下我的多條件需求,如果和您的類似,繼續往下看。

1、我的Lucene搜索會在很多地方使用,使用時的條件各不相同

2、只建立一份索引

使用的工具包(點我下載):

 

一、創建索引文件

import java.io.File;
import java.io.FileReader;
import java.nio.file.Paths;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
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.wltea.analyzer.lucene.IKAnalyzer;

public class LuceneCreateIndex
{
   private IndexWriter indexWriter = null;

   public LuceneCreateIndex( String indexDir ) throws Exception
   {
      // IKAnalyzer 有獨特之處,同時支持多種語言的分詞
      Analyzer analyzer = new IKAnalyzer();
      Directory directory = FSDirectory.open( Paths.get( indexDir ) );
      IndexWriterConfig indexWriterConfig = new IndexWriterConfig( analyzer );
      indexWriter = new IndexWriter( directory, indexWriterConfig );
   }

   /**
    * 將測試數據文件寫入索引
    * @param dataDir
    * @throws Exception
    */
   public void createIndex( String dataDir ) throws Exception
   {
      File[] files = new File( dataDir ).listFiles();
      for ( File file : files )
      {
         Document document = getDocument( file );
         indexWriter.addDocument( document );
         System.out.println( "已建立索引文件:" + file.getCanonicalPath() );
      }
      indexWriter.close();
   }

   public Document getDocument( File file ) throws Exception
   {
      Document document = new Document();
      document.add( new TextField( "contents", new FileReader( file ) ) );
      document.add( new TextField( "fileName", file.getName(), Field.Store.YES ) );
      document.add( new TextField( "fullPath", file.getCanonicalPath(), Field.Store.YES ) );
      return document;
   }

   public static void main( String[] args )
   {
      String indexDir = "D:\\luceneTest";// 索引文件生成目錄
      String dataDir = "D:\\luceneTest\\data";// 測試數據目錄(測試數據見下圖)
      try
      {
         new LuceneCreateIndex( indexDir ).createIndex( dataDir );
      }
      catch ( Exception e )
      {
         e.printStackTrace();
      }
   }
}

運行生成索引文件;測試數據如下

 

2、測試搜索效果

import java.nio.file.Paths;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class LuceneTestSearch
{
   /**
    * 單條件查詢
    * @param indexDir
    * @param q
    * @throws Exception
    */
   public static void search( String indexDir, String q ) throws Exception
   {
      Directory directory = FSDirectory.open( Paths.get( indexDir ) );
      IndexReader indexReader = DirectoryReader.open( directory );
      IndexSearcher indexSearcher = new IndexSearcher( indexReader );
      Analyzer analyzer = new IKAnalyzer();
      // 搜索目標是 contents
      QueryParser parser = new QueryParser( "contents", analyzer );
      // 傳入關鍵字,進行分析
      Query query = parser.parse( q );
      // 分頁,這里取前十個
      TopDocs topDocs = indexSearcher.search( query, 10 );

      for ( ScoreDoc scoreDoc : topDocs.scoreDocs )
      {
         // 獲取搜索結果
         Document document = indexSearcher.doc( scoreDoc.doc );
         System.out.println( document.get( "fullPath" ) );
      }

      indexReader.close();
   }

   /**
    * 多條件查詢
    * @param indexDir
    * @param q
    * @throws Exception
    */
   public static void searchBooleanQuery( String indexDir, String q ) throws Exception
   {
      Directory directory = FSDirectory.open( Paths.get( indexDir ) );
      IndexReader indexReader = DirectoryReader.open( directory );
      IndexSearcher indexSearcher = new IndexSearcher( indexReader );
      Analyzer analyzer = new IKAnalyzer();
      // 多條件必備神器
      BooleanQuery.Builder builder = new BooleanQuery.Builder();
      // 實際使用中一般是多目標搜索(根據 姓名、性別、年齡、學校等等),
      //QueryParser parser = new MultiFieldQueryParser( new String[]{"contents","fullPath"}, analyzer );
      // 條件一
      QueryParser parser = new QueryParser( "contents", analyzer );
      Query query = parser.parse( q );
      // contents必須含有條件一
      builder.add( query, Occur.MUST );
      // 條件二
      QueryParser parser1 = new QueryParser( "fileName", analyzer );
      Query query1 = parser1.parse( "b c" );
      // fileName必須不能是 b 和 c
      builder.add( query1, Occur.MUST_NOT );

      TopDocs topDocs = indexSearcher.search( builder.build(), 10 );

      for ( ScoreDoc scoreDoc : topDocs.scoreDocs )
      {
         Document document = indexSearcher.doc( scoreDoc.doc );
         System.out.println( document.get( "fullPath" ) );
      }
      indexReader.close();
   }

   public static void main( String[] args )
   {
      String indexDir = "D:\\luceneTest";
      String q = "1";
      try
      {
         // 搜索contents含有1的文件信息
         System.out.println( "單條件查詢:" );
         search( indexDir, q );
         // 搜索contents含有1 但是除開文件b 和  c
         System.out.println( "多條件查詢:" );
         searchBooleanQuery( indexDir, q );
      }
      catch ( Exception e )
      {
         e.printStackTrace();
      }
   }
}

搜索結果如下

單條件查詢:
D:\luceneTest\data\d.txt
D:\luceneTest\data\b.txt
D:\luceneTest\data\c.txt
D:\luceneTest\data\a.txt
多條件查詢:
D:\luceneTest\data\d.txt
D:\luceneTest\data\a.txt

關於更多lucene的學習,歡迎和博主交流

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM