[编程实例] Lucene Demo 小实例

本文介绍如何使用Lucene创建文件和数据库内容的索引,并实现高效搜索。通过Java代码示例展示了文件索引的过程,包括文件读取、文档添加及索引优化等步骤。同时,还提供了从SQL Server数据库中创建索引的方法,以及如何进行数据库内容的搜索。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是文件索引:

先用爬虫爬几个页面放在特定目录下,我挑取了 google,baidu,yahoo 的代码来做例子:)

Writer.java
public   class  Writer 
{
    
public static void main(String[] args) throws Exception
    
{
        
//fileDir is the directory that contains the text files to be indexed
        File fileDir = new File("D:/work/source");

        
//indexDir is the directory that hosts Lucene's index files
        File indexDir = new File("D:/work/index");
        Analyzer luceneAnalyzer 
= new StandardAnalyzer();
        IndexWriter indexWriter 
= new IndexWriter(indexDir,luceneAnalyzer,true);
        File[] textFiles 
= fileDir.listFiles();
        System.out.println(
"Total indexed "" + textFiles.length + "" files ! ");
        
        
long startTime = new Date().getTime();

        
//Add documents to the index
        for(int i = 0; i < textFiles.length; i++){
            
if (textFiles[i].isFile() && textFiles[i].getName().endsWith(".htm")) {
                System.out.println(
"File " + textFiles[i].getCanonicalPath() + " is being indexed");
                Reader textReader 
= new FileReader(textFiles[i]);
                Document document 
= new Document();
                document.add(
new Field("content",textReader));
                document.add(
new Field("path",textFiles[i].getPath(),Field.Store.YES,Field.Index.TOKENIZED));
                indexWriter.addDocument(document);
            }

        }


        indexWriter.optimize();
        indexWriter.close();
        
long endTime = new Date().getTime();

        System.out.println(
" It took " + (endTime - startTime)
            
+ " milliseconds to create an index for the files in the directory "
            
+ fileDir.getPath());
    }

}

Searcher.java
public   class  Searcher 
{
    
public static final String path = "D:/work/index";
    
    
public static void main(String[] args) throws Exception
    
{
        IndexSearcher searcher 
= new IndexSearcher(path);
        Hits hits 
= null;
        Query query 
= null;
        QueryParser qp 
= new QueryParser("content"new StandardAnalyzer());
        
        String searchText 
= "yahoo job google baidu";
        
        query 
= qp.parse(searchText);
        hits 
= searcher.search(query);
        System.out.println(
"Search "" + searchText + "" total " + hits.length() + " result ! ");
        
for (Iterator it = hits.iterator(); it.hasNext(); ) {
            Hit hit 
= (Hit) it.next();
            System.out.println(hit.getDocument().getField(
"path").stringValue());
        }

    }

}
 
以下是一个 DB 索引的例子,大家可以看看:

数据库环境:SQL Server 2005
数据库名称:mydb
数据库表:users
表结构:
Table users
PKid
 name
 pass
 updatetime

DBIndexer.java
public   class  DBIndexer 
{
    
private String driver="com.microsoft.sqlserver.jdbc.SQLServerDriver";
    
private String url="jdbc:sqlserver://localhost:1433;databaseName=mydb;";
    
private String user="sa";
    
private String pass="123456";
    
private Connection conn=null;
    
private Statement st=null;
    
private ResultSet rs=null;
    
private String indexUrl="D:/work/index/mydb";

    
private ResultSet getResult() throws Exception{        
        
try {
            Class.forName(driver);
            conn 
= DriverManager.getConnection(url, user, pass);
            String sql 
= "select * from users";
            st 
= conn.createStatement();
            rs 
= st.executeQuery(sql);
//            while (rs.next()) {
//                System.out.print(rs.getInt("id") + " ");
//                System.out.print(rs.getString("name") + " ");
//                System.out.print(rs.getString("pass") + " ");
//                System.out.print(rs.getDate("updatetime") + " ");
//            }
        }

        
catch (Exception e) {
            e.printStackTrace();
        }

        
return rs;
    }


    
private void executeIndex(ResultSet rs, IndexWriter indexWriter) throws Exception{
        
int i=0;
        
while(rs.next()){
            
int id = rs.getInt("id");
            String name 
= rs.getString("name");
            String time 
= rs.getString("updatetime");
            

            Document doc 
= new Document();

            Field idField
=new Field("id", Integer.toString(id), Field.Store.YES, Field.Index.NO, Field.TermVector.NO);
            Field nameField
=new Field("name", name, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES);
            Field timeField
=new Field("time", time, Field.Store.YES, Field.Index.TOKENIZED, Field.TermVector.YES);

            doc.add(idField);
            doc.add(nameField);
            doc.add(timeField);

            indexWriter.addDocument(doc);

            i
++;
        }

        
this.close();
        System.out.println(
"共处理记录:"+i);
    }


    
private void close() throws Exception{
        
this.rs.close();
        
this.st.close();
        
this.conn.close();
    }


    
public void createIndex() throws Exception{
        
// get data ResultSet
        ResultSet rs=this.getResult();

//        Analyzer chineseAnalyzer = new ChineseAnalyzer();
        Analyzer chineseAnalyzer = new StandardAnalyzer();
        IndexWriter indexWriter 
= new IndexWriter(this.indexUrl, chineseAnalyzer, true);
        indexWriter.setMergeFactor(
100);
        indexWriter.setMaxBufferedDocs(
100);

        java.util.Date startDate
=new java.util.Date();

        System.out.println(
"开始索引时间:" + startDate);

        executeIndex(rs, indexWriter);

        indexWriter.optimize();

        indexWriter.close();

        java.util.Date endDate
=new java.util.Date();

        System.out.println(
"索引结束时间:" + endDate);
        System.out.println(
"共花费:" + (endDate.getTime()-startDate.getTime()) + "ms");
    }

    
    
public static void main (String args[]) throws Exception {
        DBIndexer oIndexer 
= new DBIndexer();
        oIndexer.createIndex();
    }

}

DBSearcher.java
public   class  DBSearcher  {
    
    
private static final String indexUrl="D:/work/index/mydb";

    
public static void main(String[] args) throws Exception {
        
        
/*建立索引代码,查找时注释*/
        
//Index index=new Index();
        
//index.createIndex();

        File indexDir 
= new File(indexUrl);
        FSDirectory fdir 
= FSDirectory.getDirectory(indexDir);

        IndexSearcher searcher 
= new IndexSearcher(fdir);

        
//对中文建立解析(必须)
//        Analyzer chineseAnalyzer = new ChineseAnalyzer();
        Analyzer chineseAnalyzer = new StandardAnalyzer();
        QueryParser parser 
= new QueryParser("name", chineseAnalyzer);
        Query query 
= parser.parse("石头");

        Date startDate 
= new Date();
        System.out.println(
"检索开始时间:"+startDate);

        Hits result 
= searcher.search(query);

        
for(int i=0; i<result.length(); i++){
            Document doc 
= result.doc(i);
            System.out.println(
"用户ID:" + doc.get("id"+ " 更新时间:" + doc.get("time"));
        }


        Date endDate
=new Date();

        System.out.println(
"共有记录:" + result.length());
        System.out.println(
"共花费:" + (endDate.getTime()-startDate.getTime()) + "ms");
    }


}
开源全文搜索工具包Lucene2.9.1的使用。 1. 搭建Lucene的开发环境:在classpath中添加lucene-core-2.9.1.jar包 2. 全文搜索的两个工作: 建立索引文件,搜索索引. 3. Lucene的索引文件逻辑结构 1) 索引(Index)由若干块(片段)(Segment)组成 ★2) 块由若干文档(Document)组成: 一个文件映射成一个文档。数据库表中的一条记录映射成一个文档。 ★3) 文档由若干域(Field)组成:文件的属性(文件路径,文件的内容)映射成一个域。记录的某个字段映射成一个域。 ☆4) 域由若干词(关键字)(Term)组成:文件的属性的内容中某个字符串映射成一个词。 4. Lucene包结构 1) analysis模块:负责词法分析及语言处理而形成Term(词)。提供了一些内置的分析器:最常用的是StandardAnalyzer 2) index模块:负责索引的读写。 对索引文件的segment进行写、合并、优化的IndexWriter类。对索引进行读取和删除操作的IndexReader类。 3) store模块:负责索引的存储。提供索引的各种存储类:FSDirectory,RAMDirectory等。 4) document模块:索引文件内部的基础存储结构封装。如:Document类和Field类等。 5) search模块:负责对索引的搜索。提供了索引搜索器IndexSearcher类和各种Query类,如TermQuery、BooleanQuery等。 6) queryParser模块:负责查询语句的语法分析。提供了解析查询语句的QueryParser类 7) util模块:包含一些公共工具类。 5. 创建索引 1) IndexWriter:索引写出器 a) 构造方法: IndexWriter(Directory d, Analyzer a, IndexWriter.MaxFieldLength mfl) 如果索引不存在,就会被创建。如果索引存在,就追加. IndexWriter(Directory d, Analyzer a, boolean create, IndexWriter.MaxFieldLength mfl) create为true时,原索引文件不存在就创建,存在就覆盖。 create为false时,原索引文件不存在就报错,存在就追加。 b) 常用方法: void addDocument(Document doc); //把指定文档添加到索引写出器中 void iw.close(); //关闭索引写出器,此时才把索引写到目标存储地 2) Directory: 索引存放地。 a) 文件系统:FSDirectory: FSDirectory.open(File file); b) 内存RAMDirectory: new RAMDirectory(); 3) Analyzer: 分词器。 a) StandardAnalyzer: 标准分词器。对英文采用空白, 标点符号进行分词。对中文采用单字分词。 b) SmartChineseAnalyzer: 智能中文分词器。(LUCENE_HOME/contrib/analyzers/smartcn/lucene-smartcn-2.9.1.jar) C) 第三方的中文分词器:如PaodingAnalyzer、IKAnalyzer 4) IndexWriter.MaxFieldLength: 指定域值的最大长度。 a) UNLIMITED 无限制的。 b) LIMITED 有限制的。值为10000 5) Document: 索引的组成单元. 一组Field的集合. a) 构造方法: Document(); b) 常用方法: void add(Field f); //添加指定域到这个文档中 6) Field: 域,代表文档的某个索引域. a) 构造方法: Field(String name, String value, Field.Store.YES, Field.Index.ANALYZED) name: 域的名称, 只能是字符串. value: 域的值, 只能是字符串. Field.Store: 指定Field的值是否存储或怎样存储. NO(不存储), YES(存储),COMPRESS(压缩后存储) Field.Index: 指定Field是否被索引或怎么被索引. NO(不索引), ANALYZED(分词后索引), NOT_ANALYZED(不分词直接索引)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值