Lucene 全文检索实践(5) 参考指数 : 3

对于 Lucene 的初步研究已经过去一段时间,自己感觉还不是很深入,但由于时间的关系,一直也没再拿起。应网友的要求,将自己实践中写的一些代码贴出来,希望能对大家有用。程序没有做进一步的优化,只是很简单的实现功能而已,仅供参考。

在实践中,我以将 PHP 中文手册中的 HTML 文件生成索引,然后通过一个 JSP 对其进行全文检索。

生成索引的 Java 代码:

/**
 * PHPDocIndexer.java
 * 用于对 PHPDoc 的 HTML 页面生成索引文件。
 */
import java.io.File;
import java.io.FileReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Date;
import java.text.DateFormat;
import java.lang.*;

import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.DateField;

class PHPDocIndexer
{
    public static void main(String[] args) throws ClassNotFoundException, IOException
    {
        try {
            Date start = new Date();

            IndexWriter writer = new IndexWriter("/home/nio/indexes-phpdoc", new CJKAnalyzer(), true); //索引保存目录,必须存在
            indexDocs(writer, new File("/home/nio/phpdoc-zh")); //HTML 文件保存目录
            
            System.out.println("Optimizing ....");
            writer.optimize();
            writer.close();
            
            Date end = new Date();
           
            System.out.print("Total time: ");
            System.out.println(end.getTime() - start.getTime());
        } catch (Exception e) {
            System.out.println("Class " + e.getClass() + " throws error!\n  errmsg: " + e.getMessage());
        }   //end try
    }   //end main
    
    public static void indexDocs(IndexWriter writer, File file) throws Exception 
    {
        if (file.isDirectory()) {
            String[] files = file.list();
            for (int i = 0; i < files.length; i++) {
                indexDocs(writer, new File(file, files[i]));
            }   //end for
        } else if (file.getPath().endsWith(".html")) {  //只对 HTML 文件做索引           
            System.out.print("Add file:" + file + " ....");
            // Add html file ....
            Document doc = new Document();
            doc.add(Field.UnIndexed("file", file.getName()));    //索引文件名
            doc.add(Field.UnIndexed("modified", DateFormat.getDateTimeInstance().format(new Date(file.lastModified()))));   //索引最后修改时间

            String title = "";
            String content = "";
            String status = "start";
            
            FileReader fReader = new FileReader(file);
            BufferedReader bReader = new BufferedReader(fReader);
            String line = bReader.readLine();

            while (line != null) {                
                content += line;
                //截取 HTML 标题 <title>
                if ("start" == status && line.equalsIgnoreCase("><TITLE")) {
                    status = "match";
                } else if ("match" == status) {
                    title = line.substring(1, line.length() - 7);
                    doc.add(Field.Text("title", title));    //索引标题
                    status = "end";
                }   //end if
                line = bReader.readLine();
            }   //end while
            bReader.close();
            fReader.close();
            doc.add(Field.Text("content", content.replaceAll("<[^<>]+>", "")));  //索引内容
            writer.addDocument(doc);
            System.out.println(" [OK]");
        }   //end if
    }

}   //end class


索引生成完之后,就需要一个检索页面,下边是搜索页面(search.jsp)的代码:
<%@ page language="java" import="javax.servlet.*, javax.servlet.http.*, java.io.*, java.util.Date, java.util.ArrayList, java.util.regex.*, org.apache.lucene.analysis.*, org.apache.lucene.document.*, org.apache.lucene.index.*, org.apache.lucene.search.*, org.apache.lucene.queryParser.*, org.apache.lucene.analysis.Token, org.apache.lucene.analysis.TokenStream, org.apache.lucene.analysis.cjk.CJKAnalyzer, org.apache.lucene.analysis.cjk.CJKTokenizer, com.chedong.weblucene.search.WebLuceneHighlighter" %>
<%@ page contentType="text/html;charset=GB2312" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
    <title>PHPDoc - PHP 简体中文手册全文检索</title>
    <base target="main"><!-- 由于使用了 Frame,所以指定 target 到 main 窗口显示 -->
    <style>
        body {background-color: white; margin: 4px}
        body, input, div {font-family: Tahoma; font-size: 9pt}
        body, div {line-height: 18px}
        u {color: red}
        b {color: navy}
        form {padding: 0px; margin: 0px}
        .txt {border: 1px solid black}
        .f {padding: 4px; margin-bottom: 16px; background-color: #E5ECF9; border-top: 1px solid #3366CC; border-bottom: 1px solid #3366CC; text-align: center;}
        .d, .o {padding-left: 16px}
        .d {color: gray}
        .o {color: green}
        .o a {color: #7777CC}
    </style>
    <script language="JavaScript">
        function gotoPage(i)
        {
            document.frm.page.value = i;
            document.frm.submit();
        }   //end function
    </script>
</head>

<body>
<%
String keyVal = null;
String pageVal = null;
int offset = 0;
int curPage = 0;
int pages;
final int ROWS = 50;

//获取 GET 参数
try {
    byte[] keyValByte = request.getParameter("key").getBytes("ISO8859_1");  //查找关键字
    keyVal = new String(keyValByte);
    pageVal = request.getParameter("page");    //页码
} catch (Exception e) {
    //do nothing;
}
if (keyVal == null)
    keyVal = new String("");
%>
<div class="f">
    <form name="frm" action="./index.jsp" method="GET" οnsubmit="this.page.value='0';return true;" target="_self">
        <input type="text" name="key" class="txt" size="40" value="<%=keyVal%>" />
        <input type="hidden" name="page" value="<%=pageVal%>" />
        <input type="submit" value="搜  索" /><br />
        <font color="green">提示:可使用多个关键字(使用空格隔开)提高搜索的准确率。</font>
    </form>
    <script language="JavaScript">
        document.frm.key.focus();
    </script>
</div>
<%
if (keyVal != null && keyVal.length() > 0) {
    try {
        curPage = Integer.parseInt(pageVal);    //将当前页转换成整数
    } catch (Exception e) {
        //do nothing;
    }   //end try
    try {
        Date startTime = new Date();
        keyVal = keyVal.toLowerCase().replaceAll("(or|and)", "").trim().replaceAll("\\s+", " AND ");
        Searcher searcher = new IndexSearcher("/home/nio/indexes-phpdoc"); //索引目录
        Analyzer analyzer = new CJKAnalyzer();
        String[] fields = {"title", "content"};        
        Query query = MultiFieldQueryParser.parse(keyVal, fields, analyzer);
        Hits hits = searcher.search(query);

        StringReader in = new StringReader(keyVal);
        TokenStream tokenStream = analyzer.tokenStream("", in);
        ArrayList al = new ArrayList();
        for (Token token = tokenStream.next(); token != null; token = tokenStream.next()) {
            al.add(token.termText());
        }   //end for
        
        //总页数
        pages = (new Integer(hits.length()).doubleValue() % ROWS != 0) ? (hits.length() / ROWS) + 1 : (hits.length() / ROWS);

        //当前页码
        if (curPage < 1)
            curPage = 1;
        else if (curPage > pages)
            curPage = pages;
        
        //起始、终止下标
        offset = (curPage - 1) * ROWS;
        int end = Math.min(hits.length(), offset + ROWS);
        
        //循环输出查询结果
        WebLuceneHighlighter hl = new WebLuceneHighlighter(al);
        for (int i = offset; i < end; i++) {
            Document doc = hits.doc(i);
            %>
            <div class="t"><a href="/~nio/phpdoc-zh/<%=doc.get("file")%>"><%=hl.highLight(doc.get("title"))%></a></div>
            <div class="d"><%=hl.highLight(doc.get("content").replaceAll("\n", "  "), 100)%> ……</div>
            <div class="o">
                /~nio/phpdoc-zh/<%=doc.get("file")%>
                 - 
                <%=doc.get("modified")%>
            </div>
            <br />
            <%
        }   //end for
        searcher.close();
        Date endTime = new Date();
        %>
            <div class="f">
                检索总共耗时 <b><%=((endTime.getTime() - startTime.getTime()) / 1000.0)%></b> 秒,约有 <b><%=hits.length()%></b> 项符合条件的记录,共 <b><%=pages%></b> 页
        <%
        if (curPage > 1 && pages > 1) {
        %>
             | <a href="javascript:gotoPage(<%=(curPage-1)%>);" target="_self">上一页</a>
        <%
        }   //end if
        if (curPage < pages && pages > 1) {
        %>
             | <a href="javascript:gotoPage(<%=(curPage+1)%>)" target="_self">下一页</a>
        <%
        }   //end if
    } catch (Exception e) {
    %>
        <!-- <%=e.getClass()%> 导致错误:<%=e.getMessage()%> -->
    <%
    }   //end if
}   //end if
%>    
</body>
</html>

转载于:https://www.cnblogs.com/lucene/archive/2004/12/25/81701.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Lucene实现对MySQL数据表的全文检索是一种可行的方案。Lucene是一套开源的全文检索和搜寻的程式库,它提供了一个简单但强大的应用程式接口,能够实现全文索引和搜寻的功能。在Java开发环境中,Lucene是一个成熟的免费开源工具,被广泛应用于信息检索领域。 全文检索是一种针对非结构化数据的检索方法,对于像磁盘上的文件、网站资源等非结构化数据,无法使用SQL语句进行查询,因此需要使用全文检索法。全文检索法将非结构化数据中的一部分信息提取出来进行组织,形成索引,然后根据索引快速定位到要查找的信息。Lucene可以实现全文检索的功能,它是Apache软件基金会支持和提供的工具包。 使用Lucene实现全文检索的流程如下: 1. 创建索引:首先获取要进行检索的文档,可以是磁盘文件或网站资源等,然后构建文档对象,包括多个域,如文件名称、文件路径、文件大小、文件内容等。接下来对文档进行分词,将分词结果创建为索引并添加到索引库中。 2. 索引搜索:创建查询对象,执行查询并渲染结果。在倒排索引词典表中查找对应搜索词的索引,然后找到索引所链接的文档。例如,搜索语法为"fileName:lucene"表示搜索文件名中包含Lucene的文档。 要使用Lucene实现全文检索,首先需要下载和配置Lucene。你可以从官方网站或其他可信的资源下载Lucene的安装包,并按照相应的指南进行配置。然后,你可以使用Lucene提供的API来实现全文检索功能,根据具体需求进行代码编写和调用。 总之,Lucene是一种强大的全文检索工具,可以帮助你在MySQL数据表中实现全文检索功能。你可以通过学习和使用Lucene的API来了解更多关于Lucene的功能和用法,并根据具体需求进行相应的实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【springboot微服务】Lucence实现Mysql全文检索](https://blog.csdn.net/zhangcongyi420/article/details/129940816)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【Lucene&Solr】Lucene实现全文检索](https://blog.csdn.net/qq_43705275/article/details/107229299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值