1.数据分类
结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件
2.非结构化数据查询方法
(1)顺序扫描法:
所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢
(2)全文检索
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
这种先建立索引,在对索引进行搜索的过程就叫全文检索。
3.如何实现全文检索
可以使用Lucene实现全文检索。Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。
4.索引和搜索流程图
(1)索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容采集文档创建文档分析文档索引文档
(2)搜索过程,从索引库中搜索内容,搜索过程包括:用户通过搜索界面创建查询执行搜索,从索引库搜索渲染搜索结果
5.创建文档对象
在索引前需要将原始内容创建成文档,文档中包括一个一个的域(field),域中存储内容。
这里我们可以将磁盘上的一个文件当成一个document,Document中包括一些Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容)
6.分析文档
将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
每个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容
7.创建索引的步骤
第一步:创建一个java工程,并导入jar包。
第二步:创建一个indexwriter对象。
1)指定索引库的存放位置Directory对象
2)指定一个分析器,对文档内容进行分析。
第二步:创建document对象。
第三步:创建field对象,将field添加到document对象中。
第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
第五步:关闭IndexWriter对象。
8.Field域的属性
是否分析:是否对域的内容进行分词处理,前提是我们要对域的 内容进行查询
是否索引:将Field分析后的词进行索引,只有索引方可所搜到
是否存储:将Field值存在文档中,存储在文档中的Field才可以从Document中获取
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
从一个Reader字符流开始,创建一个基于Reader的Tokenizer分词器,经过三个TokenFilter生成语汇单元Tokens。
要看分析器的分析效果,只需要看Tokenstream中的内容就可以了。每个分析器都有一个方法tokenStream,返回一个tokenStream对象。
结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。
非结构化数据:指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件
2.非结构化数据查询方法
(1)顺序扫描法:
所谓顺序扫描,比如要找内容包含某一个字符串的文件,就是一个文档一个文档的看,对于每一个文档,从头看到尾,如果此文档包含此字符串,则此文档为我们要找的文件,接着看下一个文件,直到扫描完所有的文件。如利用windows的搜索也可以搜索文件内容,只是相当的慢
(2)全文检索
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对此有一定结构的数据进行搜索,从而达到搜索相对较快的目的。这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
这种先建立索引,在对索引进行搜索的过程就叫全文检索。
3.如何实现全文检索
可以使用Lucene实现全文检索。Lucene是apache下的一个开放源代码的全文检索引擎工具包。提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能。
4.索引和搜索流程图
(1)索引过程,对要搜索的原始内容进行索引构建一个索引库,索引过程包括:
确定原始内容即要搜索的内容采集文档创建文档分析文档索引文档
(2)搜索过程,从索引库中搜索内容,搜索过程包括:用户通过搜索界面创建查询执行搜索,从索引库搜索渲染搜索结果
5.创建文档对象
在索引前需要将原始内容创建成文档,文档中包括一个一个的域(field),域中存储内容。
这里我们可以将磁盘上的一个文件当成一个document,Document中包括一些Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容)
注意:每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和域值都相同)
每个文档都有一个唯一的编号,就是文档id.
将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个一个的单词。
每个单词叫做一个Term,不同的域中拆分出来的相同的单词是不同的term。term中包含两部分一部分是文档的域名,另一部分是单词的内容
7.创建索引的步骤
第一步:创建一个java工程,并导入jar包。
第二步:创建一个indexwriter对象。
1)指定索引库的存放位置Directory对象
2)指定一个分析器,对文档内容进行分析。
第二步:创建document对象。
第三步:创建field对象,将field添加到document对象中。
第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
第五步:关闭IndexWriter对象。
8.Field域的属性
是否分析:是否对域的内容进行分词处理,前提是我们要对域的 内容进行查询
是否索引:将Field分析后的词进行索引,只有索引方可所搜到
是否存储:将Field值存在文档中,存储在文档中的Field才可以从Document中获取
9.创建索引的代码(需要导包)
public class FirstLucene { @Test public void testIndex() throws Exception{ Directory directory=FSDirectory.open(new File("D:\\资料\\index")); Analyzer analyzer=new StandardAnalyzer();//官方推荐分析器 IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_4_10_3,analyzer); IndexWriter indexWriter=new IndexWriter(directory,config); //创建四个域对象(文件名,文件大小,文件内容,文件路径) //先把文件读到内存中使用IO流 File f=new File("D:\\资料\\searchsource"); File[] listFiles=f.listFiles(); for(File file:listFiles){ //创建文档对象 Document document=new Document(); //文件名字 String file_name=file.getName(); Field fileNameField=new TextField("fileName",file_name,Store.YES); //文件大小 long file_size=FileUtils.sizeOf(file); Field fileSizeField=new LongField("fileSize",file_size,Store.YES); //文件路径 String file_path=file.getPath(); Field filePathField=new StoredField("filePath",file_path); //文件内容 String file_content=FileUtils.readFileToString(file); Field fileContentField=new TextField("fileContent",file_content,Store.NO); //将域对象放到文档对象 document.add(fileNameField); document.add(fileSizeField); document.add(filePathField); document.add(fileContentField); //使用indexwriter对象将document对象写入索引库,此过程进行索引创建,并将索引和document对象放入索引库 indexWriter.addDocument(document); } //关闭IndexWriter对象 indexWriter.close(); }10.查询索引步骤
第一步:创建一个Directory对象,也就是索引库存放的位置。
第二步:创建一个indexReader对象,需要指定Directory对象。
第三步:创建一个indexsearcher对象,需要指定IndexReader对象
第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。
第五步:执行查询。
第六步:返回查询结果。遍历查询结果并输出。
第七步:关闭IndexReader对象
11.查询索引代码实现
@Test public void testSearch()throws Exception{ //创建一个Directory对象,也就是索引库位置 Directory directory=FSDirectory.open(new File("D:\\资料\\index")); //创建一个IndexReader对象,需要指定directory对象 IndexReader indexReader=DirectoryReader.open(directory); //创建一个IndexSearch对象,需要指定indexReader对象 IndexSearcher indexSearch=new IndexSearcher(indexReader); //创建一个TermQuery对象,指定查询的域和查询的关键词 Query query=new TermQuery(new Term("fileName","apache")); //执行查询 TopDocs topDocs=indexSearch.search(query, 2); //返回查询结果,遍历查询结果并返回 ScoreDoc[] scoreDocs=topDocs.scoreDocs; for(ScoreDoc scoreDoc:scoreDocs){ int doc=scoreDoc.doc; Document document=indexSearch.doc(doc); //文件名称 String fileName=document.get("fileName"); System.out.println(fileName); //文件内容 String fileContent=document.get("fileContent"); System.out.println(fileContent); //文件大小 String fileSize=document.get("fileSize"); System.out.println(fileSize); //文件路径 String filePath=document.get("filePath"); System.out.println(filePath); } //关闭流 indexReader.close(); }13.分析器
从一个Reader字符流开始,创建一个基于Reader的Tokenizer分词器,经过三个TokenFilter生成语汇单元Tokens。
要看分析器的分析效果,只需要看Tokenstream中的内容就可以了。每个分析器都有一个方法tokenStream,返回一个tokenStream对象。
14.分析器的分词效果
@Test public void testTokenStream() throws Exception { //创建一个标准分析器对象 //Analyzer analyzer = new StandardAnalyzer(); //Analyzer analyzer = new SmartChineseAnalyzer(); Analyzer analyzer = new IKAnalyzer(); //获得tokenStream对象 //第一个参数:域名,可以随便给一个 //第二个参数:要分析的文本内容 TokenStream tokenStream = analyzer.tokenStream("test", "The Spring Framework provides a comprehensive programming and configuration model."); //添加一个引用,可以获得每个关键词 CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class); //添加一个偏移量的引用,记录了关键词的开始位置以及结束位置 OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class); //将指针调整到列表的头部 tokenStream.reset(); //遍历关键词列表,通过incrementToken方法判断列表是否结束 while(tokenStream.incrementToken()) { //关键词的起始位置 System.out.println("start->" + offsetAttribute.startOffset()); //取关键词 System.out.println(charTermAttribute); //结束位置 System.out.println("end->" + offsetAttribute.endOffset()); } tokenStream.close(); }