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文件内容)
将原始内容创建为包含域(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.
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中获取
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();
}