﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-马光军--------BLOG-文章分类-Lucene</title><link>http://www.blogjava.net/maguangjun/category/35638.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 03 Dec 2008 05:06:35 GMT</lastBuildDate><pubDate>Wed, 03 Dec 2008 05:06:35 GMT</pubDate><ttl>60</ttl><item><title>利用Lucene 实现高级搜索</title><link>http://www.blogjava.net/maguangjun/articles/238109.html</link><dc:creator>马光军</dc:creator><author>马光军</author><pubDate>Sat, 01 Nov 2008 10:08:00 GMT</pubDate><guid>http://www.blogjava.net/maguangjun/articles/238109.html</guid><wfw:comment>http://www.blogjava.net/maguangjun/comments/238109.html</wfw:comment><comments>http://www.blogjava.net/maguangjun/articles/238109.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/maguangjun/comments/commentRss/238109.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/maguangjun/services/trackbacks/238109.html</trackback:ping><description><![CDATA[<table style="width: 767px; height: 1044px" cellspacing="2" cellpadding="2" width="767" border="0">
    <tbody>
        <tr>
            <td>
            <p>Lucene 支持多种形式的高级搜索，我们在这一部分中会进行探讨，然后我会使用 Lucene 的 API 来演示如何实现这些高级搜索功能。<br />
            <br />
            </p>
            <p><a><span><strong>布尔操作符</strong></span></a></p>
            <p>大多数的搜索引擎都会提供布尔操作符让用户可以组合查询，典型的布尔操作符有 AND, OR, NOT。Lucene 支持 5 种布尔操作符，分别是 AND, OR, NOT, 加(+), 减(-)。接下来我会讲述每个操作符的用法。 </p>
            <ul>
                <li><strong>OR</strong>: 如果你要搜索含有字符 A 或者 B 的文档，那么就需要使用 OR 操作符。需要记住的是，如果你只是简单的用空格将两个关键词分割开，其实在搜索的时候搜索引擎会自动在两个关键词之间加上 OR 操作符。例如，&#8220;Java OR Lucene&#8221; 和 &#8220;Java Lucene&#8221; 都是搜索含有 Java 或者含有 Lucene 的文档。
                <li><strong>AND</strong>: 如果你需要搜索包含一个以上关键词的文档，那么就需要使用 AND 操作符。例如，&#8220;Java AND Lucene&#8221; 返回所有既包含 Java 又包含 Lucene 的文档。
                <li><strong>NOT</strong>: Not 操作符使得包含紧跟在 NOT 后面的关键词的文档不会被返回。例如，如果你想搜索所有含有 Java 但不含有 Lucene 的文档，你可以使用查询语句 &#8220;Java NOT Lucene&#8221;。但是你不能只对一个搜索词使用这个操作符，比如，查询语句 &#8220;NOT Java&#8221; 不会返回任何结果。
                <li><strong>加号（+）</strong>: 这个操作符的作用和 AND 差不多，但它只对紧跟着它的一个搜索词起作用。例如，如果你想搜索一定包含 Java，但不一定包含 Lucene 的文档，就可以使用查询语句&#8220;+Java Lucene&#8221;。
                <li><strong>减号（-）</strong>: 这个操作符的功能和 NOT 一样，查询语句 &#8220;Java -Lucene&#8221; 返回所有包含 Java 但不包含 Lucene 的文档。 </li>
            </ul>
            <p><a><span><strong>域搜索(Field Search)</strong></span></a></p>
            <p>Lucene 支持域搜索，你可以指定一次查询是在哪些域(Field)上进行。例如，如果索引的文档包含两个域，<code>Title</code> 和 <code>Content</code>，你就可以使用查询 &#8220;Title: Lucene AND Content: Java&#8221; 来返回所有在 Title 域上包含 Lucene 并且在 Content 域上包含 Java 的文档。<br />
            <br />
            </p>
            <p><a><span><strong>通配符搜索(Wildcard Search)</strong></span></a></p>
            <p>Lucene 支持两种通配符：问号（？）和星号（*）。你可以使用问号（？）来进行单字符的通配符查询，或者利用星号（*）进行多字符的通配符查询。例如，如果你想搜索 tiny 或者 tony，你就可以使用查询语句 &#8220;t?ny&#8221;；如果你想查询 Teach, Teacher 和 Teaching，你就可以使用查询语句 &#8220;Teach*&#8221;。<br />
            </p>
            <p><a><span><strong>模糊查询</strong></span></a></p>
            <p>Lucene 提供的模糊查询基于编辑距离算法(Edit distance algorithm)。你可以在搜索词的尾部加上字符 ~ 来进行模糊查询。例如，查询语句 &#8220;think~&#8221; 返回所有包含和 think 类似的关键词的文档。<br />
            </p>
            <p><a><span><strong>范围搜索(Range Search)</strong></span></a></p>
            <p>范围搜索匹配某个域上的值在一定范围的文档。例如，查询 &#8220;age:[18 TO 35]&#8221; 返回所有 age 域上的值在 18 到 35 之间的文档。</p>
            </td>
        </tr>
    </tbody>
</table>
转载地址：http://www.cnblogs.com/weekzero/articles/1224064.html
 <img src ="http://www.blogjava.net/maguangjun/aggbug/238109.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/maguangjun/" target="_blank">马光军</a> 2008-11-01 18:08 <a href="http://www.blogjava.net/maguangjun/articles/238109.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Lucene软件包分析</title><link>http://www.blogjava.net/maguangjun/articles/238108.html</link><dc:creator>马光军</dc:creator><author>马光军</author><pubDate>Sat, 01 Nov 2008 09:57:00 GMT</pubDate><guid>http://www.blogjava.net/maguangjun/articles/238108.html</guid><wfw:comment>http://www.blogjava.net/maguangjun/comments/238108.html</wfw:comment><comments>http://www.blogjava.net/maguangjun/articles/238108.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/maguangjun/comments/commentRss/238108.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/maguangjun/services/trackbacks/238108.html</trackback:ping><description><![CDATA[<table style="width: 762px; height: 461px" cellspacing="2" cellpadding="2" width="762" border="0">
    <tbody>
        <tr>
            <td>
            <p>Lucene 软件包的发布形式是一个 JAR 文件，下面我们分析一下这个 JAR 文件里面的主要的 JAVA 包，使读者对之有个初步的了解。</p>
            <p>Package: org.apache.lucene.document</p>
            <p>这个包提供了一些为封装要索引的文档所需要的类，比如 Document, Field。这样，每一个文档最终被封装成了一个 Document 对象。</p>
            <p>Package: org.apache.lucene.analysis</p>
            <p>这个包主要功能是对文档进行分词，因为文档在建立索引之前必须要进行分词，所以这个包的作用可以看成是为建立索引做准备工作。</p>
            <p>Package: org.apache.lucene.index</p>
            <p>这个包提供了一些类来协助创建索引以及对创建好的索引进行更新。这里面有两个基础的类：IndexWriter 和 IndexReader，其中 IndexWriter 是用来创建索引并添加文档到索引中的，IndexReader 是用来删除索引中的文档的。</p>
            <p>Package: org.apache.lucene.search</p>
            <p>这个包提供了对在建立好的索引上进行搜索所需要的类。比如 IndexSearcher 和 Hits, IndexSearcher 定义了在指定的索引上进行搜索的方法，Hits 用来保存搜索得到的结果。</p>
            </td>
        </tr>
    </tbody>
</table>
<table style="width: 760px; height: 33px" cellspacing="2" cellpadding="2" width="760" border="0">
    <tbody>
        <tr>
            <td>
            <p><a name="N10094"><span class="atitle">建立索引</span></a></p>
            <p>为了对文档进行索引，Lucene 提供了五个基础的类，他们分别是 Document, Field, IndexWriter, Analyzer, Directory。下面我们分别介绍一下这五个类的用途：</p>
            <p><strong>Document</strong></p>
            <p>Document 是用来描述文档的，这里的文档可以指一个 HTML 页面，一封电子邮件，或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录，而每个 Field 对象就是记录的一个字段。</p>
            <p><strong>Field</strong></p>
            <p>Field 对象是用来描述一个文档的某个属性的，比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。</p>
            <p><strong>Analyzer</strong></p>
            <p>在一个文档被索引之前，首先需要对文档内容进行分词处理，这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类，它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。</p>
            <p><strong>IndexWriter</strong></p>
            <p>IndexWriter 是 Lucene 用来创建索引的一个核心的类，他的作用是把一个个的 Document 对象加到索引中来。</p>
            <p><strong>Directory</strong></p>
            <p>这个类代表了 Lucene 的索引的存储的位置，这是一个抽象类，它目前有两个实现，第一个是 FSDirectory，它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory，它表示一个存储在内存当中的索引的位置。</p>
            <p>熟悉了建立索引所需要的这些类后，我们就开始对某个目录下面的文本文件建立索引了，清单1给出了对某个目录下的文本文件建立索引的源代码。</p>
            </td>
        </tr>
    </tbody>
</table>
<a name="N100C3"><strong>清单 1. 对文本文件建立索引</strong></a><br />
<table style="width: 1111px; height: 964px" cellspacing="2" cellpadding="2" width="1111" border="0">
    <tbody>
        <tr>
            <td>
            <pre class="displaycode">package TestLucene;
            import java.io.File;
            import java.io.FileReader;
            import java.io.Reader;
            import java.util.Date;
            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.index.IndexWriter;
            /**
            * This class demonstrate the process of creating index with Lucene
            * for text files
            */
            public class TxtFileIndexer {
            public static void main(String[] args) throws Exception{
            //indexDir is the directory that hosts Lucene's index files
            File   indexDir = new File("D:\\luceneIndex");
            //dataDir is the directory that hosts the text files that to be indexed
            File   dataDir  = new File("D:\\luceneData");
            Analyzer luceneAnalyzer = new StandardAnalyzer();
            File[] dataFiles  = dataDir.listFiles();
            IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
            long startTime = new Date().getTime();
            for(int i = 0; i &lt; dataFiles.length; i++){
            if(dataFiles[i].isFile() &amp;&amp; dataFiles[i].getName().endsWith(".txt")){
            System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
            <!-- code sample is too wide -->        		Document document = new Document();
            Reader txtReader = new FileReader(dataFiles[i]);
            document.add(Field.Text("path",dataFiles[i].getCanonicalPath()));
            document.add(Field.Text("contents",txtReader));
            indexWriter.addDocument(document);
            }
            }
            indexWriter.optimize();
            indexWriter.close();
            long endTime = new Date().getTime();
            System.out.println("It takes " + (endTime - startTime)
            + " milliseconds to create index for the files in directory "
            + dataDir.getPath());
            }
            }</pre>
            <pre class="displaycode">
            <p>在清单1中，我们注意到类 IndexWriter 的构造函数需要三个参数，第一个参数指定了所创建的索引要存放的位置，他可以是一个 File 对象，<br />
            也可以是一个 FSDirectory 对象或者 RAMDirectory 对象。<br />
            第二个参数指定了 Analyzer 类的一个实现，也就是指定这个索引是用哪个分词器对文挡内容进行分词。<br />
            第三个参数是一个布尔型的变量，如果为 true 的话就代表创建一个新的索引，为 false 的话就代表在原来索引的基础上进行操作。<br />
            接着程序遍历了目录下面的所有文本文档，并为每一个文本文档创建了一个 Document 对象。<br />
            然后把文本文档的两个属性：路径和内容加入到了两个 Field 对象中，接着在把这两个 Field 对象加入到 Document 对象中，<br />
            最后把这个文档用 IndexWriter 类的 add 方法加入到索引中去。这样我们便完成了索引的创建。接下来我们进入在建立好的索引上进行搜索的部分。</p>
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<table style="width: 767px; height: 1616px" cellspacing="2" cellpadding="2" width="767" border="0">
    <tbody>
        <tr>
            <td>
            <p><a name="N100CF"><span class="atitle">搜索文档</span></a></p>
            <p>利用Lucene进行搜索就像建立索引一样也是非常方便的。在上面一部分中，我们已经为一个目录下的文本文档建立好了索引，现在我们就要在这个索引上进行搜索以找到包含某个关键词或短语的文档。Lucene提供了几个基础的类来完成这个过程，它们分别是呢IndexSearcher, Term, Query, TermQuery, Hits. 下面我们分别介绍这几个类的功能。</p>
            <p><strong>Query</strong></p>
            <p>这是一个抽象类，他有多个实现，比如TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成Lucene能够识别的Query。</p>
            <p><strong>Term</strong></p>
            <p>Term是搜索的基本单位，一个Term对象有两个String类型的域组成。生成一个Term对象可以有如下一条语句来完成：Term term = new Term(&#8220;fieldName&#8221;,&#8221;queryWord&#8221;); 其中第一个参数代表了要在文档的哪一个Field上进行查找，第二个参数代表了要查询的关键词。</p>
            <p><strong>TermQuery</strong></p>
            <p>TermQuery是抽象类Query的一个子类，它同时也是Lucene支持的最为基本的一个查询类。生成一个TermQuery对象由如下语句完成： TermQuery termQuery = new TermQuery(new Term(&#8220;fieldName&#8221;,&#8221;queryWord&#8221;)); 它的构造函数只接受一个参数，那就是一个Term对象。</p>
            <p><strong>IndexSearcher</strong></p>
            <p>IndexSearcher是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引，所以可以有多个IndexSearcher的实例在一个索引上进行操作。</p>
            <p><strong>Hits</strong></p>
            <p>Hits是用来保存搜索的结果的。</p>
            <p>介绍完这些搜索所必须的类之后，我们就开始在之前所建立的索引上进行搜索了，清单2给出了完成搜索功能所需要的代码。</p>
            <br />
            <a name="N100FE"><strong>清单2 ：在建立好的索引上进行搜索</strong></a><br />
            <table cellspacing="0" cellpadding="0" width="100%" border="0">
                <tbody>
                    <tr>
                        <td class="code-outline">
                        <pre class="displaycode">package TestLucene;
                        import java.io.File;
                        import org.apache.lucene.document.Document;
                        import org.apache.lucene.index.Term;
                        import org.apache.lucene.search.Hits;
                        import org.apache.lucene.search.IndexSearcher;
                        import org.apache.lucene.search.TermQuery;
                        import org.apache.lucene.store.FSDirectory;
                        /**
                        * This class is used to demonstrate the
                        * process of searching on an existing
                        * Lucene index
                        *
                        */
                        public class TxtFileSearcher {
                        public static void main(String[] args) throws Exception{
                        String queryStr = "lucene";
                        //This is the directory that hosts the Lucene index
                        File indexDir = new File("D:\\luceneIndex");
                        FSDirectory directory = FSDirectory.getDirectory(indexDir,false);
                        IndexSearcher searcher = new IndexSearcher(directory);
                        if(!indexDir.exists()){
                        System.out.println("The Lucene index is not exist");
                        return;
                        }
                        Term term = new Term("contents",queryStr.toLowerCase());
                        TermQuery luceneQuery = new TermQuery(term);
                        Hits hits = searcher.search(luceneQuery);
                        for(int i = 0; i &lt; hits.length(); i++){
                        Document document = hits.doc(i);
                        System.out.println("File: " + document.get("path"));
                        }
                        }
                        }
                        </pre>
                        </td>
                    </tr>
                </tbody>
            </table>
            <br />
            <p>在清单2中，类IndexSearcher的构造函数接受一个类型为Directory的对象，Directory是一个抽象类，它目前有两个子类：FSDirctory和RAMDirectory. 我们的程序中传入了一个FSDirctory对象作为其参数，代表了一个存储在磁盘上的索引的位置。构造函数执行完成后，代表了这个IndexSearcher以只读的方式打开了一个索引。然后我们程序构造了一个Term对象，通过这个Term对象，我们指定了要在文档的内容中搜索包含关键词&#8221;lucene&#8221;的文档。接着利用这个Term对象构造出TermQuery对象并把这个TermQuery对象传入到IndexSearcher的search方法中进行查询，返回的结果保存在Hits对象中。最后我们用了一个循环语句把搜索到的文档的路径都打印了出来。好了，我们的搜索应用程序已经开发完毕，怎么样，利用Lucene开发搜索应用程序是不是很简单。</p>
            </td>
        </tr>
    </tbody>
</table>
<br />
转载地址：http://www-128.ibm.com/developerworks/cn/java/j-lo-lucene1/
 <img src ="http://www.blogjava.net/maguangjun/aggbug/238108.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/maguangjun/" target="_blank">马光军</a> 2008-11-01 17:57 <a href="http://www.blogjava.net/maguangjun/articles/238108.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>