Lucence学习笔记

Lucence学习笔记 2017-07-16

数据的分类

1. 结构化数据

概述:有固定类型或者有固定长度的数据,例如:数据库中的数据(mysql,oracle等), 元数据(就是windows中的数据)。

  • 结构化数据的搜索方法:数据库中数据通过sql语句可以搜索;元数据(windows中的)通过windows提供的搜索栏进行搜索。

2. 非结构化数据

概述:没有固定类型和固定长度的数据,例如: world文档中的数据, 邮件中的数据

  • 非结构化数据的搜索方法:Word文档使用ctrl+F来搜索
    • 顺序扫描法:Ctrl+F中是使用的顺序扫描法,拿到搜索的关键字,去文档中,逐字匹配,直到找到和关键字一致的内容为止。
      • 优点: 如果文档中存在要找的关键字就一定能找到想要的内容
      • 缺点: 慢, 效率低
    • 全文检索算法(倒排索引算法)
      • 将文件中的内容提取出来, 将文字拆封成一个一个的词(分词), 将这些词组成索引(字典中的目录), 搜索的时候先搜索索引,通过索引找文档,这个过程就叫做全文检索
      • 分词: 去掉停用词(a, an, the ,的, 地, 得, 啊, 嗯 ,呵呵),因为搜索的时候搜索这些词没有意义,将句子拆分成词,去掉标点符号和空格
      • 优点: 搜索速度快
      • 缺点: 因为创建的索引需要占用磁盘空间,所以这个算法会使用掉更多的磁盘空间,这是用空间换时间思
        想的体现
  • 原理
     相当于字典,分为目录和正文两部分,查询的时候通过先查目录,然后通过目录上标注的页数去正文页查找需要的内容。

感悟:建立索引的过程,其实就是建立字典的目录的过程

Lucence

1.Lucence结构

Lucence学习笔记_第1张图片
Paste_Image.png
  • 索引(index)

  • 文档(docudment)

感悟:Document对象其实就是对真实文件的一个抽取,抽取的过程中就是将文件的各种属性以域的概述进行了封装,比如一个文件包含很多属性:文件名,文件内容,文件大小,文件格式等,最终将多个 Field对象封装进了一个Document对象。(Document也可以封装数据库的一条记录,可以将需要进行索引的字段封装成document对象的 field)
索引:Document生成后,如果希望快速的进行检索,那么就需要对文档中的 field进行分词,分词后最小的单位是term(词元),哪些field要分词,哪些field不分词,是由field的类型决定的,比如StringField就是不进行分词的

创建索引测试类示例代码

/**
 * 创建索引测试类
 * @author 77376
 *
 */
public class IndexManageTest {
    
    @Test
    public void testIndexCreate() throws IOException{
        //创建文档列表,保存多个document
        List docList = new ArrayList<>();
        
        //采集文档系统中的文档数据,放入Lucence
        File dir = new File("F:\\KuGou\\searchsource");
        //循环文件夹,取出文件
        for(File file : dir.listFiles()){
            //文件名
            String fileName = file.getName();
            //文件内容
            String fileContent = FileUtils.readFileToString(file);
            //文件大小
            Long fileSize = FileUtils.sizeOf(file);
            
            //文档对象,文件系统中的一个文件就是一个文档对象
            Document doc = new Document();
            //第一个参数:域名
            //第二个参数:域值 
            //第三个参数:是否存储,是为yes,不存储为no
            TextField nameField = new TextField("fileName", fileName, Store.YES);
            TextField contentField = new TextField("fileContent", fileContent, Store.YES);
            TextField sizeField = new TextField("fileSize", fileSize.toString(), Store.YES);
            
            //将所有的域都存入文档中
            doc.add(nameField);
            doc.add(contentField);
            doc.add(sizeField);
            
            //将文档存入文档集合中
            docList.add(doc);
        }
        
        //创建分词器,标准分词器,对英文分词效果好,对中文是单字分词
        Analyzer analyzer = new StandardAnalyzer();
        
        //指定索引和文档存储目录
        Directory directory = FSDirectory.open(new File("F:\\KuGou\\dir"));
        IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);
        //创建索引和 文档写对象
        IndexWriter indexWriter = new IndexWriter(directory, config);
        
        //将文档加入到索引和文档的写对象中
        for(Document doc : docList){
            indexWriter.addDocument(doc); 
        }
        
        //提交
        indexWriter.commit();
        //关闭
        indexWriter.close();
    }
}

基于Lucence的索引进行搜索示例代码

/**
 * Lucence搜索示例代码
 * @author 77376
 *
 */
public class IndexSearchTest {
    
    @Test
    public void testIndexSearch() throws Exception{
        //创建分词器(搜索时使用的分词器必须与创建索引时使用的分词器一致)
        Analyzer analyzer = new StandardAnalyzer();
        //创建查询对象
        //第一个参数:默认搜索域
        //第二个参数:分词器
        //默认搜索域的作用:如何搜索语法中指定域名,就从指定域名中搜索,如果搜索时只写了查询关键字,则从默认搜索域中搜索
        QueryParser queryParser = new QueryParser("fileContent", analyzer);
        //查询语法: 域名:搜索的关键字
        //Query query = queryParser.parse("fileName:apache");
        Query query = queryParser.parse("java");
        
        //指定索引和文档的目录
        Directory directory = FSDirectory.open(new File("F:\\KuGou\\dir"));
        //索引和文档的读取对象
        IndexReader indexReader = IndexReader.open(directory);
        
        //创建索引的搜索对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        
        //第一个参数:指定查询语句对象
        //第二个参数:指定显示多少条
        TopDocs topDocs = indexSearcher.search(query, 5);
        System.out.println("--------count--------" + topDocs.totalHits);
        //从搜索结果对象中获取结果集
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            //获取docID
            int docID = scoreDoc.doc;
            //通过文档ID,从硬盘中取出对应的文档
            Document document = indexReader.document(docID);
            System.out.println("fileName : " + document.get("fileName"));
            System.out.println("fileSize : " + document.get("fileSize"));
            System.out.println("-------line-------");
        }
    }
}

查询方式(检索类型)

  • TermQuery:
    根据词进行搜索(只能从文本中进行搜索)
  • QueryParser:
    根据域名进行搜索,可以设置默认搜索域,推荐使用. (只能从文本中进行搜索)
  • NumericRangeQuery:
    从数值范围进行搜索
  • BooleanQuery:
    组合查询,可以设置组合条件,not and or.从多个域中进行查询
    must相当于and关键字,是并且的意思
    should,相当于or关键字或者的意思
    must_not相当于not关键字, 非的意思
    注意:单独使用must_not 或者 独自使用must_not没有任何意义
  • MatchAllDocsQuery:
    查询出所有文档
  • MultiFieldQueryParser:
    可以从多个域中进行查询,只有这些域中有关键词的存在就查询出来

你可能感兴趣的:(Lucence学习笔记)