• 搜索引擎lucene实现二半吊子的论调之体系结构


    写这个东西就是两个目的,一是让自己头脑清醒,一是让别人把咱的头脑弄清醒。技术这个东西跟本能一个样,只要你愿意用成就本能的方式去学习技术,谁都可以成就自己。

    因为咱不是文科出身,工作了六年,也没有那些牛逼人士的韧力和魄力,曾经就想着能多写写技术博客,但总是没有坚持下去(深叹一口气,你可别像我这样。。)。前些日子又看了一下《康熙王朝》(陈道明演的),被里面的一句话(一言之虚,百患丛生; 一事之虚,遗害终生。)给击蒙了,于是重新想着坚持下去。刚好要跟同事分享lucene,那么也就多学,多看,多想,多写了。

    OK,言归正传,到底搜索引擎有多神秘?

    对我来说,lucene的出现,没有多少影响,因为当初我还在一个小公司里面糊里糊涂地混日子,而虽然听说过这个东西,但没有用过,仅了解了一下。但自从去了那个网络公司之后,要做搜索系统,我就切实地接触到了这个开源神器。至少在一定程度上讲,让我觉得Google,百度不是那么神奇的公司了。因为他们就是用超大规模的爬虫,倒排表,超大规模的缓存和我不知道的超大的things。

    小差时刻:作为一个非计算机专业的从业人员,从一定程度上讲,个人表示很惭愧。尽管有编程之热情,但却没有彻底地钻研从业用到的每个组成部分,这实在有点非专业的风格。我想这个浮躁的社会可能会让很多人变成(编程)这样,Matrix造就了我们追求成果不管原理的工作方式。(抱怨一下,但这是自我深深的反省。)

    看一段lucene官网的示例代码:

     1 import org.apache.lucene.analysis.Analyzer;
     2 import org.apache.lucene.analysis.standard.StandardAnalyzer;
     3 import org.apache.lucene.document.Document;
     4 import org.apache.lucene.document.Field;
     5 import org.apache.lucene.document.TextField;
     6 import org.apache.lucene.index.DirectoryReader;
     7 import org.apache.lucene.index.IndexWriter;
     8 import org.apache.lucene.index.IndexWriterConfig;
     9 import org.apache.lucene.queryparser.classic.QueryParser;
    10 import org.apache.lucene.search.IndexSearcher;
    11 import org.apache.lucene.search.Query;
    12 import org.apache.lucene.search.ScoreDoc;
    13 import org.apache.lucene.store.Directory;
    14 import org.apache.lucene.store.RAMDirectory;
    15 import org.apache.lucene.util.Version;
    16 
    17 public final class TestLucene {
    18 
    19     public static void main(String[] args) throws Exception{
    20         Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
    21 
    22         // Store the index in memory:
    23         Directory directory = new RAMDirectory();
    24         // To store an index on disk, use this instead:
    25         //Directory directory = FSDirectory.open("/tmp/testindex");
    26         IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
    27         IndexWriter iwriter = new IndexWriter(directory, config);
    28         Document doc = new Document();
    29         String text = "This is the text to be indexed.";
    30         doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
    31         iwriter.addDocument(doc);
    32         iwriter.close();
    33         
    34         // Now search the index:
    35         DirectoryReader ireader = DirectoryReader.open(directory);
    36         IndexSearcher isearcher = new IndexSearcher(ireader);
    37         // Parse a simple query that searches for "text":
    38         QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer);
    39         Query query = parser.parse("text");
    40         ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
    41         // Iterate through the results:
    42         for (int i = 0; i < hits.length; i++) {
    43           Document hitDoc = isearcher.doc(hits[i].doc);
    44           System.out.println(hitDoc.get("fieldname"));
    45         }
    46         ireader.close();
    47         directory.close();
    48     }
    49     
    50 }

    声明:以上这段代码,main里面的代码都是取自lucene官网的。但也要特别说明一下,在maven pom.xml里面,对于lucene4.0版本的依赖配置如下:

    <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-core</artifactId>
    <version>4.0.0</version>
    </dependency>
    <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-analyzers-common</artifactId>
    <version>4.0.0</version>
    </dependency>
    <dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>4.0.0</version>
    </dependency>

    好像3.x版本的不需要这么多配置的吧(好像又好久没跟进lucene测试了。。呵呵)

    仅仅从这个demo的import里面,我们能看到lucene的基本功能结构分割:

    Lucene是一个文本内容的全文检索系统,从上图我们也可以看出lucene的确有比较明确且抽象的架构设计。

    IndexWriter:接收业务数据,并将索引好的数据写入到Store中。IndexWriter在接收数据时,主要依靠封装了文本内容及其元数据的Document(org.apache.lucene.document,夹缝中引用一下,实在是委屈了Document,它也是具有皇室直系血统的类,非常重要。),它在org.apache.lucene.index包中。index包主要管理索引创建阶段用到的各种类,如IndexReader, IndexWriter....(还有很多底层类,不一一列举,但后面在详细说明时,会一一分析。)

    Store:这是一个相对底层的组织,对应包为org.apache.lucene.store,其主要包含与索引数据文件读写管理相关的各种类。

    IndexSearcher: 这个是使用Query数据对索引数据进行检索的类。猜得出来,它在org.apache.lucene.search中。

    QueryParser:它也是存在于org.apache.lucene.search中,并且其主要职责是解析用户的输入字符串,并返回Query对象,然后供IndexSearcher使用,其对IndexSearcher的重要性跟Docment之于IndexWriter有的一拼。

    Analyzer:最后才说到Analyzer,并不是说它不重要,相反它极其重要。Analyzer类主要用户对文本内容进行分词处理,而分词质量的好坏关系到搜索结果的相关度,所以也就有了针对不同文化和语言的各种Analyzer。正如图中展现的,建立和查询索引时都要用到它,是居家旅行的必备良药。

    对于网络用户来说,他们只需要关心query data(就是他们想搜的关键词或者句子),经过Parser解析成关键字的query(queryparser的结果),经由IndexSearcher来查询Indexed Data,并返回结果。而我们在对目标数据建索引的过程,则是经由IndexWriter来解析和分解处理,然后将解析的结果(这是个big problem)保存成Indexed Data。

    这里要区分一下,网络用户他们只想查找关心的数据,所以他们输入:关键词;而我们开发者则有业务数据。这里就是说,在使用lucene时,是否需要想想以下几个方面:

    数据获取:提供用于接收业务数据的接口,搜索请求处理接口;

    lucene封装:组装索引Document的接口,返回结果的封装接口,更重要的是log接口(统计和实验);

    瞻前顾后,咱会从Analyzer,Document,Index,Search and Store几个方面,给各位分享一下lucene的情况。

    一点点来,不着急。。。。。

     
  • 相关阅读:
    P3373 【模板】线段树 2
    P3372 【模板】线段树 1
    P3368 【模板】树状数组 2
    P3374 【模板】树状数组 1
    P1004 方格取数
    P1880 [NOI1995]石子合并
    UOJ#152盘子序列
    P1886 滑动窗口
    P1440 求m区间内的最小值
    二进制中1的个数
  • 原文地址:https://www.cnblogs.com/ericchen/p/2776269.html
Copyright © 2020-2023  润新知