Lucene基础

发布 : 2016-01-20 分类 : 大数据 浏览 :

1.什么是lucene

1
2
3
Lucene是一个全文搜索框架,而不是应用产品。

因此它并不像http://www.baidu.com/或者google Desktop那么拿来就能用,

2.Lucene能做什么

1
2
3
要回答这么问题,先要了解Lucene的本质。实际上Lucene的功能很单一,说到底,就是你给它若干个字符串,
然后它为你提供一个全文搜索服务,告诉你给你要搜索的关键词出现在哪里。知道了这个本质,你就可以发挥想象做任何符合这个条件的事情了。你可以把站内新闻
都索引了,做好这个资料库。你就可以把一个数据库的若干字段索引起来,那就不用担心因为"%like%"而锁表了;你也可以写个自己的搜索引擎

3.你该不该选择lucene(性能)

1
2
3
4
5
下面给出一些测试数据,如果你觉得可以接受,那么可以选择

测试一:250万记录,300M左右文本,生成索引380M左右,生成索引380M左右,800线程下平均处理时间300ms

测试二:37000记录,索引数据库中的两个varchar字段,索引文件2.6m,800线程下平均处理时间1.5ms

4.Luncene为什么这么快

1
2
3
倒排索引(要掌握)
压缩算法
二元搜索

5.倒排索引

1
2
3
4
根据属性的值来查找记录。这种索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址。由于不是由记录来确定属性值,而是由属性值来确定记录的位置,
因而成为倒排索引(invertedindex)

单词-文档矩阵

6.Lucene的工作方式

1
2
Lucene提供的服务实际包含两部分:一入一出。所谓入是写入,即将你提供的源(本质是字符串)写入索引或者将其从索引中删除;
所谓出是读出,即向用户提供全文搜索服务,让用户可以通过关键词定位源

7.写入流程

1
2
3
源字符串首先经过analyzer处理,包括:分词。分成一个个单词;去除stopword(可选),将源中需要的信息加入Document的各个Field中,
并把需要索引的Field索引起来,把需要存储的Field存储起来
将索引写入存储器,存储器可以是内存或磁盘

8.读出流程

1
2
3
用户提供搜索关键词,进过analyzer处理
对处理后的关键词搜索索引找出对应的Document
用户根据需要从找到Document中提取需要的Field

document

1
2
用户提供的源是一条条记录,它们可以是文本文件.字符串或者数据库表的一条记录等等。一条记录经过索引之后,就是以一个Document的形式存储在索引文件中。
用户进行搜索,也是以Document列表的形式返回

field

1
2
3
4
5
6
一个Document可以包含多个信息域,例如一篇文章可以包含"标题"."正文"."最后修改时间"等信息域,这些信息域就是通过Field在Document中存储的

Field有两个属性可选:
存储和索引。通过存储属性你可以控制是否对这个Field进行存储;
通过索引属性你可以控制是否对该Field进行索引。
这看起来似乎有些废话,事实上对这个两个属性的正确组合很重要

8.1.导入Lucene相关jar包

8.2.创建索引

Index.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package com.matrix.lucene;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class Index {

// 创建索引
@Test
public void createIndex() throws Exception {
Directory dir = FSDirectory.open(new File("F:\\index"));
IndexWriterConfig conf = new IndexWriterConfig(Version.LUCENE_4_9, new StandardAnalyzer(Version.LUCENE_4_9));
IndexWriter iw = new IndexWriter(dir, conf);
// 写索引
File file = new File("F:\\software\\centos\\lucene");
File[] files = file.listFiles();
List<Document> docs = new ArrayList<Document>();
// for循环遍历
for (File f : files) {
TextField content = new TextField("content", FileUtils.readFileToString(f), Store.YES);
StringField fileName = new StringField("fileName", f.getName(), Field.Store.YES);
LongField modifyTime = new LongField("modifyTime", f.lastModified(), Field.Store.YES);
Document doc = new Document();
doc.add(content);
doc.add(fileName);
doc.add(modifyTime);
docs.add(doc);
}
iw.addDocuments(docs);
iw.commit();
iw.close();
}
}

8.3.查询索引

Index.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.matrix.lucene;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.LongField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;

public class Index {

// 查询索引
@Test
public void search() throws Exception {
IndexReader reader = DirectoryReader.open(FSDirectory.open(new File("F:\\index")));
IndexSearcher searcher = new IndexSearcher(reader);
QueryParser qp = new QueryParser(Version.LUCENE_4_9, "content", new StandardAnalyzer(Version.LUCENE_4_9));
Query query = qp.parse("Spring");
TopDocs search = searcher.search(query, 10);
ScoreDoc[] score = search.scoreDocs;
for (ScoreDoc sd : score) {
int docId = sd.doc;
Document document = reader.document(docId);
System.out.println(document.get("fileName"));
}

}
}

8.4.运行结果:

1
2
3
4
5
6
2.Serving Web Content.txt
1.create web page.txt
spring.txt
spring_README.txt
springmvc.txt
cxf_README.txt

本文作者 : Matrix
原文链接 : https://matrixsparse.github.io/2016/01/20/lucene基础/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!

知识 & 情怀 | 二者兼得

微信扫一扫, 向我投食

微信扫一扫, 向我投食

支付宝扫一扫, 向我投食

支付宝扫一扫, 向我投食

留下足迹