全文检索技术---Lucene

1       Lucene介绍

1.1   什么是Lucene

Lucene是apache下的一个开源的全文检索引擎工具包。它为软件开发人员提供一个简单易用的工具包(类库),以方便的在目标系统中实现全文检索的功能。

1.2   全文检索的应用场景

1.2.1  搜索引擎

©注意:

Lucene和搜索引擎是不同的,Lucene是一套用java或其它语言写的全文检索的工具包。它为应用程序提供了很多个api接口去调用,可以简单理解为是一套实现全文检索的类库。搜索引擎是一个全文检索系统,它是一个单独运行的软件系统。

1.2.2  站内搜索(关注)

1.3  全文检索定义

  全文检索首先将要查询的目标文档中的词提取出来,组成索引,通过查询索引达到搜索目标文档的目的。这种先建立索引,再对索引进行搜索的过程就叫全文检索(Full-text Search

2       Lucene实现全文检索的流程

全文检索的流程分为两大部分:索引流程、搜索流程。

  • 索引流程:即采集数据à构建文档对象à分析文档(分词)à创建索引。
  • 搜索流程:即用户通过搜索界面à创建查询à执行搜索,搜索器从索引库搜索à渲染搜索结果。

3       入门程序

  3.1.1  第一步:添加jar包

入门程序只需要添加以下jar包:

  1. mysql5.1驱动包:mysql-connector-java-5.1.7-bin.jar
  2. 核心包:lucene-core-4.10.3.jar
  3. 分析器通用包:lucene-analyzers-common-4.10.3.jar
  4. 查询解析器包:lucene-queryparser-4.10.3.jar

   3.1.2  PO,DAO以及测试代码

      

 1 package cn.xjy.po ;
 2
 3 public class Book {
 4
 5     // 图书ID
 6     private Integer    id ;
 7     // 图书名称
 8     private String    name ;
 9     // 图书价格
10     private Float    price ;
11     // 图书图片
12     private String    pic ;
13     // 图书描述
14     private String    description ;
15
16     public Book() {}
17
18     public Book(Integer id, String name, Float price, String pic, String description) {
19         super() ;
20         this.id = id ;
21         this.name = name ;
22         this.price = price ;
23         this.pic = pic ;
24         this.description = description ;
25     }
26
27     public Integer getId() {
28         return id ;
29     }
30
31     public void setId(Integer id) {
32         this.id = id ;
33     }
34
35     public String getName() {
36         return name ;
37     }
38
39     public void setName(String name) {
40         this.name = name ;
41     }
42
43     public Float getPrice() {
44         return price ;
45     }
46
47     public void setPrice(Float price) {
48         this.price = price ;
49     }
50
51     public String getPic() {
52         return pic ;
53     }
54
55     public void setPic(String pic) {
56         this.pic = pic ;
57     }
58
59     public String getDescription() {
60         return description ;
61     }
62
63     public void setDescription(String description) {
64         this.description = description ;
65     }
66
67     @Override
68     public String toString() {
69         return "Book [id=" + id + ", name=" + name + ", price=" + price + ", pic=" + pic
70                 + ", description=" + description + "]" ;
71     }
72
73 }

    

 1 package cn.xjy.dao ;
 2
 3 import java.sql.Connection ;
 4 import java.sql.DriverManager ;
 5 import java.sql.PreparedStatement ;
 6 import java.sql.ResultSet ;
 7 import java.util.ArrayList ;
 8 import java.util.List ;
 9 import cn.xjy.po.Book ;
10
11 public class BookDaoImpl implements BookDao {
12
13     @Override
14     public List<Book> getBooks() {
15         List<Book> books = new ArrayList<Book>() ;
16
17         try {
18             Class.forName("com.mysql.jdbc.Driver") ;
19             Connection con = DriverManager.getConnection("jdbc:mysql:///luncene", "root", "root") ;
20             PreparedStatement statement = con.prepareStatement("select * from book") ;
21             ResultSet resultSet = statement.executeQuery() ;
22             while (resultSet.next()) {
23                 Book book = new Book(resultSet.getInt("id"), resultSet.getString("name"),
24                         resultSet.getFloat("price"), resultSet.getString("pic"),
25                         resultSet.getString("description")) ;
26                 books.add(book) ;
27             }
28         } catch (Exception e) {
29             e.printStackTrace() ;
30         }
31
32         return books ;
33     }
34
35 }

 

  1 package cn.xjy.lucene ;
  2
  3 import java.io.File ;
  4 import java.util.ArrayList ;
  5 import java.util.List ;
  6 import org.apache.lucene.analysis.Analyzer ;
  7 import org.apache.lucene.analysis.standard.StandardAnalyzer ;
  8 import org.apache.lucene.document.Document ;
  9 import org.apache.lucene.document.Field ;
 10 import org.apache.lucene.document.Field.Store ;
 11 import org.apache.lucene.document.FloatField ;
 12 import org.apache.lucene.document.IntField ;
 13 import org.apache.lucene.document.TextField ;
 14 import org.apache.lucene.index.DirectoryReader ;
 15 import org.apache.lucene.index.IndexReader ;
 16 import org.apache.lucene.index.IndexWriter ;
 17 import org.apache.lucene.index.IndexWriterConfig ;
 18 import org.apache.lucene.index.Term ;
 19 import org.apache.lucene.queryparser.classic.QueryParser ;
 20 import org.apache.lucene.search.BooleanClause.Occur ;
 21 import org.apache.lucene.search.BooleanQuery ;
 22 import org.apache.lucene.search.IndexSearcher ;
 23 import org.apache.lucene.search.NumericRangeQuery ;
 24 import org.apache.lucene.search.Query ;
 25 import org.apache.lucene.search.ScoreDoc ;
 26 import org.apache.lucene.search.TermQuery ;
 27 import org.apache.lucene.search.TopDocs ;
 28 import org.apache.lucene.store.Directory ;
 29 import org.apache.lucene.store.FSDirectory ;
 30 import org.apache.lucene.util.Version ;
 31 import org.wltea.analyzer.lucene.IKAnalyzer ;
 32 import cn.xjy.dao.BookDao ;
 33 import cn.xjy.dao.BookDaoImpl ;
 34 import cn.xjy.po.Book ;
 35
 36 public class TestLucene {
 37
 38     /**
 39      * 创建索引库
 40      * @throws Exception
 41      */
 42     public void lucene() throws Exception {
 43         BookDao bookDao = new BookDaoImpl() ;
 44         List<Book> books = bookDao.getBooks() ;
 45         // 采集数据的目的是为了索引,在索引前需要将原始内容创建成文档(Document),
 46         // 文档(Document)中包括一个一个的域(Field)。
 47
 48         // 1.创建document集合对象
 49         List<Document> documents = new ArrayList<Document>() ;
 50
 51         // 2.循环遍历数据集,根据需求创建不同的filed,添加到对应的document对象中
 52         Document document = null ;
 53         for (Book book : books) {
 54             document = new Document() ;
 55             Field id = new IntField("id", book.getId(), Store.YES) ;
 56             Field name = new TextField("name", book.getName(), Store.YES) ;
 57
 58             if (book.getId()==4)
 59                 name.setBoost(100f) ;// 设置权重.值越大搜索越靠前
 60             Field price = new FloatField("price", book.getPrice(), Store.YES) ;
 61             Field pic = new TextField("pic", book.getPic(), Store.YES) ;
 62             Field description = new TextField("description", book.getDescription(), Store.NO) ;
 63
 64             document.add(id) ;
 65             document.add(name) ;
 66             document.add(price) ;
 67             document.add(pic) ;
 68             document.add(description) ;
 69             documents.add(document) ;
 70         }
 71
 72         // 3.把每个document对象添加到document集合中
 73
 74         // 4.分析文档,对文档中的内容记性分词,实例化分析器对象,首先创建索引目录
 75         Analyzer analyzer = new StandardAnalyzer() ;
 76         Directory directory = FSDirectory.open(new File("src/index")) ;
 77
 78         // 5.创建indexWriterConfig对象
 79         IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer) ;
 80
 81         // 6.创建indexWriter对象
 82         IndexWriter writer = new IndexWriter(directory, config) ;
 83
 84         // 7.通过indexWriter对象,添加文档对象,写入索引库的过程
 85         for (Document doc : documents) {
 86             writer.addDocument(doc) ;
 87         }
 88
 89         // 8.关闭indexWriter流
 90         writer.close() ;
 91
 92     }
 93
 94     /**
 95      * 创建索引库,可解析中文
 96      * @throws Exception
 97      */
 98     public void luceneCN() throws Exception {
 99         BookDao bookDao = new BookDaoImpl() ;
100         List<Book> books = bookDao.getBooks() ;
101         // 采集数据的目的是为了索引,在索引前需要将原始内容创建成文档(Document),
102         // 文档(Document)中包括一个一个的域(Field)。
103
104         // 1.创建document集合对象
105         List<Document> documents = new ArrayList<Document>() ;
106
107         // 2.循环遍历数据集,根据需求创建不同的filed,添加到对应的document对象中
108         Document document = null ;
109         for (Book book : books) {
110             document = new Document() ;
111             Field id = new IntField("id", book.getId(), Store.YES) ;
112             Field name = new TextField("name", book.getName(), Store.YES) ;
113
114             if (book.getId()==4)
115                 name.setBoost(100f) ;// 设置权重.值越大搜索越靠前
116             Field price = new FloatField("price", book.getPrice(), Store.YES) ;
117             Field pic = new TextField("pic", book.getPic(), Store.YES) ;
118             Field description = new TextField("description", book.getDescription(), Store.YES) ;
119
120             document.add(id) ;
121             document.add(name) ;
122             document.add(price) ;
123             document.add(pic) ;
124             document.add(description) ;
125             documents.add(document) ;
126         }
127
128         // 3.把每个document对象添加到document集合中
129
130         // 4.分析文档,对文档中的内容记性分词,实例化分析器对象,首先创建索引目录
131         Analyzer analyzer = new IKAnalyzer();
132         Directory directory = FSDirectory.open(new File("src/index")) ;
133
134         // 5.创建indexWriterConfig对象
135         IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer) ;
136
137         // 6.创建indexWriter对象
138         IndexWriter writer = new IndexWriter(directory, config) ;
139
140         // 7.通过indexWriter对象,添加文档对象,写入索引库的过程
141         for (Document doc : documents) {
142             writer.addDocument(doc) ;
143         }
144
145         // 8.关闭indexWriter流
146         writer.close() ;
147
148     }
149
150     /**
151      * 删除指定的索引
152      * @throws Exception
153      */
154     public void deleteIndex() throws Exception {
155         // 1.指定索引库的位置
156         Directory directory = FSDirectory.open(new File("src/index")) ;
157
158         // 2.创建indexWriterConfig
159         IndexWriterConfig indexWriterConfig = new IndexWriterConfig(Version.LATEST, null) ;
160
161         // 3.创建indexWriter
162         IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig) ;
163
164         // 4.删除指定的索引(new Term())
165         // indexWriter.deleteDocuments(new Term("id", "1"));//参数是Term()
166         // indexWriter.deleteDocuments(new QueryParser("id", new
167         // StandardAnalyzer()).parse("id:1"));//参数为query
168         indexWriter.deleteAll() ;// 删除所有
169         // 5.关闭流
170         indexWriter.close() ;
171
172         System.out.println("删除成功") ;
173
174         // 在查询一遍验证是否删除
175         searchIndex() ;
176     }
177
178     /**
179      * 更新索引,
180      * 最好的做法是先查出要修改的索引进行更新
181      * @throws Exception
182      */
183     public void updateIndex() throws Exception {
184         // 1.指定索引库
185         Directory directory = FSDirectory.open(new File("src/index")) ;
186
187         // 2.定义indexReader
188         IndexReader indexReader = DirectoryReader.open(directory) ;
189
190         // 3.定义indexSearcher
191         IndexSearcher indexSearcher = new IndexSearcher(indexReader) ;
192
193         Query query = new QueryParser("id", new StandardAnalyzer()).parse("id:1") ;
194         // 查询索引库
195         TopDocs topDocs = indexSearcher.search(query, 1) ;
196
197         // 获取查询到的对象
198         ScoreDoc scoreDoc = topDocs.scoreDocs[0] ;
199
200         // 获取document对象
201         Document document = indexSearcher.doc(scoreDoc.doc) ;
202
203         // 更新内容
204         document.removeField("name") ;
205         document.add(new TextField("name", "这是测试更新的内容", Store.YES)) ;
206
207         // 初始化indexWriterConfig和indexWriter对象
208         IndexWriterConfig IndexWriterConfig = new IndexWriterConfig(Version.LATEST,
209                 new StandardAnalyzer()) ;
210         IndexWriter indexWriter = new IndexWriter(directory, IndexWriterConfig) ;
211
212         // 开始更新,这个方法第一个参数如果设置为null,则不会删除原来的数据,而且添加了一条更新后的新数据
213         // 为了保证数据的严谨性,必须删除为更新之前的数据,添加上更新后的数据就哦了
214         indexWriter.updateDocument(new Term("id", "1"), document) ;
215         indexWriter.close() ;
216         indexReader.close() ;
217
218         System.out.println("更新成功") ;
219     }
220
221     /**
222      * 可多条件连接QueryParser会将用户输入的查询表达式解析成Query对象实例。
223      * 搜索 Query query = queryParser.parse("*:*") ;
224      * @throws Exception
225      */
226     public void searchIndex() throws Exception {
227         // 创建分析器
228         Analyzer analyzer = new StandardAnalyzer() ;
229
230         // 查询条件
231         QueryParser queryParser = new QueryParser("description", analyzer) ;
232         Query query = queryParser.parse("description:个") ;
233
234         // 指定搜索目录
235         Directory directory = FSDirectory.open(new File("src/index")) ;
236
237         // 创建indexReader
238         IndexReader indexReader = DirectoryReader.open(directory) ;
239
240         // 创建indexSearch对象
241         IndexSearcher indexSearcher = new IndexSearcher(indexReader) ;
242
243         // 查询索引库
244         TopDocs topDocs = indexSearcher.search(query, 10) ;
245
246         // 获取前十条记录
247         ScoreDoc [] scoreDocs = topDocs.scoreDocs ;
248
249         System.out.println("文档个数:" + topDocs.totalHits) ;
250
251         for (ScoreDoc scoreDoc : scoreDocs) {
252             Document doc = indexSearcher.doc(scoreDoc.doc) ;
253             System.out.println(doc) ;
254         }
255     }
256
257     /**
258      * 这种不可多条件查询
259      * 搜索 Query query = new TermQuery(new Term("id", "1"));
260      * @throws Exception
261      */
262     public void searchIndex2() throws Exception {
263         // 创建分析器
264         Analyzer analyzer = new StandardAnalyzer() ;
265
266         // 查询条件
267         Query query = new TermQuery(new Term("description", "徐景洋驻马店")) ;
268
269         // 指定搜索目录
270         Directory directory = FSDirectory.open(new File("src/index")) ;
271
272         // 创建indexReader
273         IndexReader indexReader = DirectoryReader.open(directory) ;
274
275         // 创建indexSearch对象
276         IndexSearcher indexSearcher = new IndexSearcher(indexReader) ;
277
278         // 查询索引库
279         TopDocs topDocs = indexSearcher.search(query, 10) ;
280
281         // 获取前十条记录
282         ScoreDoc [] scoreDocs = topDocs.scoreDocs ;
283
284         System.out.println("文档个数:" + topDocs.totalHits) ;
285
286         for (ScoreDoc scoreDoc : scoreDocs) {
287             Document doc = indexSearcher.doc(scoreDoc.doc) ;
288             System.out.println(doc) ;
289         }
290     }
291
292     /**
293      * NumericRangeQuery,指定数字范围查询.(创建field类型时,注意与之对应)
294      * 搜索 Query query = NumericRangeQuery.newIntRange("id", 1, 9, true, true);
295      * @throws Exception
296      */
297     public void searchIndex3() throws Exception {
298         // 创建分析器
299         Analyzer analyzer = new StandardAnalyzer() ;
300
301         // 查询条件
302         // 创建查询
303         // 第一个参数:域名
304         // 第二个参数:最小值
305         // 第三个参数:最大值
306         // 第四个参数:是否包含最小值
307         // 第五个参数:是否包含最大值
308
309         Query query = NumericRangeQuery.newIntRange("id", 1, 9, true, true) ;
310
311         // 指定搜索目录
312         Directory directory = FSDirectory.open(new File("src/index")) ;
313
314         // 创建indexReader
315         IndexReader indexReader = DirectoryReader.open(directory) ;
316
317         // 创建indexSearch对象
318         IndexSearcher indexSearcher = new IndexSearcher(indexReader) ;
319
320         // 查询索引库
321         TopDocs topDocs = indexSearcher.search(query, 10) ;
322
323         // 获取前十条记录
324         ScoreDoc [] scoreDocs = topDocs.scoreDocs ;
325
326         System.out.println("文档个数:" + topDocs.totalHits) ;
327
328         for (ScoreDoc scoreDoc : scoreDocs) {
329             Document doc = indexSearcher.doc(scoreDoc.doc) ;
330             System.out.println(doc) ;
331         }
332     }
333
334     /**
335      *   1、MUST和MUST表示“与”的关系,即“并集”。
336          2、MUST和MUST_NOT前者包含后者不包含。
337          3、MUST_NOT和MUST_NOT没意义
338          4、SHOULD与MUST表示MUST,SHOULD失去意义;
339          5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。
340          6、SHOULD与SHOULD表示“或”的概念。
341
342      * BooleanQuery,布尔查询,实现组合条件查询。
343      * 搜索 BooleanQuery query = new BooleanQuery() ;
344      * @throws Exception
345      */
346     public void searchIndex4() throws Exception {
347         // 创建分析器
348         Analyzer analyzer = new StandardAnalyzer() ;
349
350         // 查询条件
351         BooleanQuery query = new BooleanQuery() ;
352
353         Query query1 = new TermQuery(new Term("name", "spring")) ;
354         Query query2 = NumericRangeQuery.newFloatRange("price", 60f, 80f, true, true) ;
355
356         // MUST:查询条件必须满足,相当于AND
357         // SHOULD:查询条件可选,相当于OR
358         // MUST_NOT:查询条件不能满足,相当于NOT非
359         query.add(query2, Occur.SHOULD) ;
360         query.add(query1, Occur.MUST) ;
361
362         // 指定搜索目录
363         Directory directory = FSDirectory.open(new File("src/index")) ;
364
365         // 创建indexReader
366         IndexReader indexReader = DirectoryReader.open(directory) ;
367
368         // 创建indexSearch对象
369         IndexSearcher indexSearcher = new IndexSearcher(indexReader) ;
370
371         // 查询索引库
372         TopDocs topDocs = indexSearcher.search(query, 10) ;
373
374         // 获取前十条记录
375         ScoreDoc [] scoreDocs = topDocs.scoreDocs ;
376
377         System.out.println("文档个数:" + topDocs.totalHits) ;
378
379         for (ScoreDoc scoreDoc : scoreDocs) {
380             Document doc = indexSearcher.doc(scoreDoc.doc) ;
381             System.out.println(doc) ;
382         }
383     }
384
385 }

 1 package cn.xjy.test ;
 2
 3 import org.junit.Test ;
 4 import cn.xjy.lucene.TestLucene ;
 5
 6 public class MyTest {
 7
 8     @Test
 9     public void testIndex() throws Exception {
10         TestLucene lucene = new TestLucene() ;
11         // lucene.lucene();
12         lucene.luceneCN() ;
13         System.out.println("创建成功") ;
14     }
15
16     @Test
17     public void testSearch() throws Exception {
18         TestLucene lucene = new TestLucene() ;
19         // lucene.searchIndex();
20         lucene.searchIndex2() ;
21         // lucene.searchIndex3();
22         // lucene.searchIndex4();
23     }
24
25     @Test
26     public void testDelete() throws Exception {
27         TestLucene lucene = new TestLucene() ;
28         lucene.deleteIndex() ;
29     }
30
31     @Test
32     public void testUpdate() throws Exception {
33         TestLucene lucene = new TestLucene() ;
34         lucene.updateIndex() ;
35     }
36 }

配置文件:IKAnalyzer.cfg.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
 3 <properties>
 4
 5     <comment>IK Analyzer 扩展配置</comment>
 6     <!-- 用户可以在这里配置自己的扩展字典 -->
 7     <entry key="ext_dict">mydict.dic</entry>
 8     <!-- 用户可以在这里配置自己的扩展停用词字典 -->
 9     <entry key="ext_stopwords">ext_stopword.dic</entry>
10
11 </properties>

4      Field域

4.1   Field属性

  Field是文档中的域,包括Field名和Field值两部分,一个文档可以包括多个Field,Document只是Field的一个承载体,Field值即为要索引的内容,也是要搜索的内容。

是否分词(tokenized)

是:作分词处理,即将Field值进行分词,分词的目的是为了索引。

比如:商品名称、商品简介等,这些内容用户要输入关键字搜索,由于搜索的内容格式大、内容多需要分词后将语汇单元索引。

否:不作分词处理

比如:商品id、订单号、身份证号等

是否索引(indexed)

是:进行索引。将Field分词后的词或整个Field值进行索引,索引的目的是为了搜索。

比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。

否:不索引。该域的内容无法搜索到

比如:商品id、文件路径、图片路径等,不用作为查询条件的不用索引。

是否存储(stored)

是:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取。

比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。

否:不存储Field值,不存储的Field无法通过Document获取

比如:商品简介,内容较大不用存储。如果要向用户展示商品简介可以从系统的关系数据库中获取商品简介。

4.2   Field常用类型

  下边列出了开发中常用 的Filed类型,注意Field的属性,根据需求选择:

  


Field类


数据类型


Analyzed

是否分词


Indexed

是否索引


Stored

是否存储


说明


StringField(FieldName, FieldValue,Store.YES))


字符串


N


Y


Y或N


这个Field用来构建一个字符串Field,但是不会进行分词,会将整个串存储在索引中,比如(订单号,身份证号等)

是否存储在文档中用Store.YES或Store.NO决定


LongField(FieldName, FieldValue,Store.YES)


Long型


Y


Y


Y或N


这个Field用来构建一个Long数字型Field,进行分词和索引,比如(价格)

是否存储在文档中用Store.YES或Store.NO决定


StoredField(FieldName, FieldValue)


重载方法,支持多种类型


N


N


Y


这个Field用来构建不同类型Field

不分析,不索引,但要Field存储在文档中


TextField(FieldName, FieldValue, Store.NO)

TextField(FieldName, reader)


字符串


Y


Y


Y或N


如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.

5   使用中文分词器IKAnalyzer

  IKAnalyzer继承Lucene的Analyzer抽象类,使用IKAnalyzer和Lucene自带的分析器方法一样,将Analyzer测试代码改为IKAnalyzer测试中文分词效果。

如果使用中文分词器ik-analyzer,就在索引和搜索程序中使用一致的分词器ik-analyzer。

5.1 添加jar包

      

  • 代码部分在上面的部分包含有中文解析.
时间: 2024-10-05 15:52:14

全文检索技术---Lucene的相关文章

全文检索技术与Lucene的使用

概念 在谈全文检索之前,首先让我们来了解一下什么是信息检索.信息检索就是从信息集合中找出与用户需求相关的信息.被检索的信息除了文本外,还有图像.音频.视频等多媒体信息,这里我们只讨论文本信息的检索. 全文检索是信息检索技术的一种,主要是把用户的查询请求和全文中的每一个词进行比较,不考虑查询请求与文本语义上的匹配.在信息检索工具中,全文检索是最具通用性和实用性的. 流程 建立索引 搜索的目的是为了在大量的信息中发现自己感兴趣的信息.但是,当有了足够的资料(比如网页.Word文档.Pdf文档,或数据

全文检索之lucene入门篇HelloWorld

首先,先看下目录结构. 第一步,在eclipse中建立jave项目.需要引入jar包,只有3个,分别是lucene的分词器和核心包,还有高亮显示器.做法是建立一个lib文件夹,将jar包拷过来,然后右击,选择Build Path(构建路径),Addto Build Path(添加到项目的构建路径). 然后建立datasource文件夹,添几个txt的文件进去,内容爱写啥写啥.(但是建议是一个是中文,一个是英文,可以测两种语言的分词).还有luceneIndex文件夹,用来存放创建的索引. 其中,

全文检索之lucene的优化篇--创建索引库

在上一篇HelloWorld的基础上,建立一个directory的包,添加一个DirectoryTest的测试类,用来根据指定的索引目录创建目录存放指引. DirectoryTest类中的代码如下,基本上就是在HelloWorld的基础上改改就可以了. 里面一共三个方法,testDirectory(),测试创建索引库;testDirectoryFSAndRAM(),结合方法1的两种创建方式,优化;testDirectoryOptimize(),在方法2个基础上,研究索引的优化创建,减少创建的索引

全文检索之lucene的优化篇--分词器

在创建索引库的基础上,加上中文分词器的,更好的支持中文的查询.引入jar包je-analysis-1.5.3.jar,极易分词.还是先看目录. 建立一个分词器的包,analyzer,准备一个AnalyzerTest的类.里面的代码如下,主要写了一个testAnalyzer的方法,测试多种分词器对于中文和英文的分词;为了可以看到效果,所以写了个analyze()的方法,将分词器和text文本内容传入,并将分词的效果显示出来. package com.lucene.analyzer; import

全文检索之lucene的优化篇--增删改查

主要介绍增删改查索引的功能,并且对于查询到的关键字,返回高亮的结果.高亮的效果,就是将查询出来的结果,在前后加上标签,<font color="red">和</font>这样在浏览器显示的就是红色的字体. 目录效果如上,建立一个com.lucene的包,建立一个IndexDao的类,里面写入索引的增删改查方法;而建立的IndexDaoText类则是对这增删改查的测试;QueryResult则是一个查询结果的类,里面只有2个字段,总记录数和记录集合. 其中Inde

lucene全文检索技术

1:lucene的介绍 全文检索引擎工具包.作用:使用lucene进行全文检索 .可以直接运行. 什么是全文检索.全文检索的场景,搜索引擎,搜索商品. 站内搜索,只会搜索自己站内的资源 全文检索首先将要查询的目标文档中的词提取出来,组成索引,通过查询索引达到搜索的文档的目的 这种先建立索引,在对索引进行搜索的过程就叫全文检索. 索引就类似于书籍的目录,目标文档就相当于书籍中的内容 搜索书籍中的内容,如果不通过目录,很费劲 其实,全文检索就是相当于给书籍编写目录. 2:Lucene实现全文检索的流

全文检索技术---solr

1       Solr介绍 1.1   什么是solr Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Solr可以独立运行在Jetty.Tomcat等这些Servlet容器中. Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置.可扩展,并对索引.搜索性能进行了优化. 使用Solr 进行创建索引和搜索索引的实现方法很简单,如下: l  创建索引:客户端(可以是浏览器可以是Java程序)用 POST 方法向 Solr 服务器发

【手把手教你全文检索】Lucene索引的【增、删、改、查】

    阅读目录 创建索引 增量添加索引 删除索引 更新索引 通过索引查询关键字 全部代码 参考资料 前言 搞检索的,应该多少都会了解Lucene一些,它开源而且简单上手,官方API足够编写些小DEMO.并且根据倒排索引,实现快速检索.本文就简单的实现增量添加索引,删除索引,通过关键字查询,以及更新索引等操作. 目前博猪使用的不爽的地方就是,读取文件内容进行全文检索时,需要自己编写读取过程(这个solr免费帮我们实现).而且创建索引的过程比较慢,还有很大的优化空间,这个就要细心下来研究了. 回到

Lucene全文检索之-Lucene基础

Lucene是全文检索引擎 一.在学习Lucene之前我们先思考下,Lucene存在的意义. 1.在之前我们的应用场景中,基于数据库的检索,我们使用like语法进行.但是基于like语法效率低下.达不到我们对应用的使用要求. 而使用Lucene对我们的数据建立索引效率高速度快,满足企业要求. 我们使用Lucene先对整个结构建立索引库,然后根据索引去查找我们需要匹配的内容,效率高速度快,方便我们快速检索信息-这也是Lucene存在的目的. 2.有些查找数据库做不了,比如我们想查找附件中内容的匹配