Lucene01

数据分类

结构化数据和非结构化数据

结构化数据搜索

sql

非结构化数据查询方法

顺序扫描法

全文检索

lucene实现全文检索的流程

创建索引

  对文档索引的过程,将用户要搜索的文档内容进行索引,索引存在索引库中,

获取原始文档

创建文档对象,文档中包括一个一个的域(Field),域中存储内容,可以将磁盘上的一个文件当成一个document,                         Document中包括一些Field(file_name文件名称、file_path文件路径、file_size文件大小、file_content文件内容)

    每个Document可以有多个Field,不同的Document可以有不同的Field,同一个Document可以有相同的Field(域名和               域值都相同)

    每个文档都有一个唯一的编号,就是文档id。

分析文档

    将原始内容创建为包含域(Field)的文档(document),需要再对域中的内容进行分析,分析的过程是经过对原始文                 档提取单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的语汇单元,可以将语汇单元理解为一个                   一个的单词

创建索引

    对所有文档分析得出的语汇单元进行索引,索引的目的是为了搜索,最终要实现只搜索被索引的语汇单元从而找到                      Document(文档)

创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构

举例:通过关键字搜索文件

jar文件

commons-io-2.6.jar
IK-Analyzer-1.0-SNAPSHOT.jar
lucene-analyzers-common-7.4.0.jar
lucene-core-7.4.0.jar
lucene-queryparser-7.4.0.jar

 1 public class LuenceFirsrt {
 2
 3
 4     /**
 5      * 1创建一个Director对象,指定索引库保存的位置
 6      * 2.基于Director对象创建一个IndexWrite对象
 7      * 3.读取磁盘上文件,对应每个文件创建一个文档对象
 8      * 4.向文档对象中添加域
 9      * 5.向文档对象中写入索引库
10      * 6.关闭indexwrite对象
11      */
12     //创建索引库
13     @Test
14     public void createIndex() throws Exception{
15         Directory directory = FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath());
16
17         IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig());
18
19         File dir = new File("D:\\lucene\\demo\\searchsource");
20         File[] files = dir.listFiles();
21
22         for(File f :files) {
23             String fileName = f.getName();
24             String filePath = f.getPath();
25
26             String fileContent = FileUtils.readFileToString(f, "utf-8");
27             long fileSize = FileUtils.sizeOf(f);
28
29             Field fieldName = new TextField("name",fileName,Field.Store.YES);
30
31             Field fieldPath = new TextField("path",filePath,Field.Store.YES);
32
33             Field fieldContent = new TextField("content",fileContent,Field.Store.YES);
34
35             Field fieldSize = new TextField("size",fileSize+"",Field.Store.YES);
36
37             Document document = new Document();
38             document.add(fieldName);
39             document.add(fieldPath);
40             document.add(fieldContent);
41             document.add(fieldSize);
42
43
44             indexWriter.addDocument(document);
45
46
47         }
48         indexWriter.close();
49     }
50 }

查询索引

 1 //查询索引库
 2     /**
 3      *         /**
 4          * 1.创建一个Director对象,指定索引库位置
 5          * 2.创建一个IndexReader对象
 6          * 3.创建一个IndexSearch 对象,构造方法中的参数indexReader对象
 7          * 4.创建一个Query对象,TermQuery
 8          * 5.执行查询,得到一个TopDocs对象
 9          * 6.取查询结果的总记录数
10          * 7.取文档列表
11          * 8.打印文档内容
12          * 9.关闭indexReader对象
13     */
14     @Test
15     public void searchIndex() throws Exception{
16
17
18         Directory directory = FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath());
19
20         IndexReader indexReader = DirectoryReader.open(directory);
21
22         IndexSearcher indexSearcher = new IndexSearcher(indexReader);
23
24         Query query = new TermQuery(new Term("content","spring"));
25
26         TopDocs topDocs = indexSearcher.search(query, 10);
27
28         System.out.println("查询记录总数为"+ topDocs.totalHits);
29
30         ScoreDoc[] scoreDocs = topDocs.scoreDocs;
31
32         for(ScoreDoc doc : scoreDocs) {
33             int docId = doc.doc;
34             Document document = indexSearcher.doc(docId);
35             System.out.println(document.get("name"));
36             System.out.println(document.get("path"));
37             System.out.println(document.get("size"));
38             System.out.println(document.get("content"));
39             System.out.println("----------------------");
40         }
41
42         indexReader.close();
43     }
44     

查看分词效果

 1     @Test
 2     public void testTokenStream() throws Exception {
 3         /**
 4          * 1.创建一个Analyzer对象,StandardAnalyzer
 5          * 2.使用分析器对象的tokenStream方法获得tokenStream对象
 6          * 3.向TokenStream对象中设置一个引用,相当于数一个指针
 7          * 4.调用TokenStream对象的rest方法
 8          * 5.使用while循环遍历ToeknStream对象
 9          * 6.关闭TokenStream对象
10          */
11
12         Analyzer analyzer = new StandardAnalyzer();
13         TokenStream tokenStream = analyzer.tokenStream("", "The Spring Framework provides a comprehensive programming and configuration model.");
14         CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
15         tokenStream.reset();
16
17         while(tokenStream.incrementToken()) {
18             System.out.println(charTermAttribute.toString());
19         }
20
21         tokenStream.close();
22     }
23     

查看中文分词器效果

第一步:把jar包添加到工程中

第二步:把配置文件和扩展词典和停用词词典添加到classpath下

注意:hotword.dic和ext_stopword.dic文件的格式为UTF-8

 1 public class Ikanalyzer {
 2     @Test
 3     public void testCHTokenStream() throws Exception {
 4         /**
 5          * 1.创建一个Analyzer对象,StandardAnalyzer
 6          * 2.使用分析器对象的tokenStream方法获得tokenStream对象
 7          * 3.向TokenStream对象中设置一个引用,相当于数一个指针
 8          * 4.调用TokenStream对象的rest方法
 9          * 5.使用while循环遍历ToeknStream对象
10          * 6.关闭TokenStream对象
11          */
12
13         Analyzer analyzer = new IKAnalyzer();
14         TokenStream tokenStream = analyzer.tokenStream("", "由于日前美方宣称拟对3000亿美元中国输美商品加征10%关税,严重违背中美两国元首大阪会晤共识");
15         CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
16         tokenStream.reset();
17
18         while(tokenStream.incrementToken()) {
19             System.out.println(charTermAttribute.toString());
20         }
21
22         tokenStream.close();
23     }
24
25 }

索引库的维护

是否分析,是否索引,是否存储


Field类


数据类型


Analyzed

是否分析


Indexed

是否索引


Stored

是否存储


说明


StringField(FieldName, FieldValue,Store.YES))


字符串


N


Y


Y或N


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

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


LongPoint(String name, long... point)


Long型


Y


Y


N


可以使用LongPoint、IntPoint等类型存储数值类型的数据。让数值类型可以进行索引。但是不能存储数据,如果想存储数据还需要使用StoredField。


StoredField(FieldName, FieldValue)


重载方法,支持多种类型


N


N


Y


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

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


TextField(FieldName, FieldValue, Store.NO)

TextField(FieldName, reader)


字符串


Y


Y


Y或N


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

添加文档

 1 public class IndexManager {
 2
 3
 4     /**
 5      * 添加文档
 6      *创建一个indexWriter对象,需要使用ik作为分词器
 7      *创建一个Document对象
 8      *向document对象添加域
 9      *把文档写入索引库
10      *关闭索引库
11      */
12     @Test
13     public void addDocument() throws Exception{
14         IndexWriter indexWriter =
15                 new IndexWriter(FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath()),
16                         new IndexWriterConfig(new IKAnalyzer()));
17
18         Document document = new Document();
19         document.add(new TextField("name","新添加的文件",Field.Store.YES));
20         document.add(new TextField("content","新添加的文件内容",Field.Store.NO));
21         document.add(new StoredField("path","D:\\lucene\\demo\\path"));
22
23
24         indexWriter.addDocument(document);
25         indexWriter.close();
26     }

删除索引

 1 public class Delete {
 2
 3     private IndexWriter indexWriter;
 4
 5     @Before
 6     public void init() throws Exception {
 7          indexWriter =
 8                  new IndexWriter(FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath()),
 9                         new IndexWriterConfig(new IKAnalyzer()));
10     }
11
12     @Test
13     public void deleteAllDocument() throws Exception {
14         indexWriter.deleteAll();
15         indexWriter.close();
16
17     }
18
19     //根据查询条件删除索引
20     @Test
21     public void deleteDocumentByQuery() throws Exception {
22         indexWriter.deleteDocuments(new Term("name","apache"));
23         indexWriter.close();
24     }
25
26 }

修改索引

先删除后添加

 1 /**
 2  *1.创建Document对象
 3  *2.向Document中添加域
 4  *3.不同的Document中有不同的域,同一个document中有相同的域
 5  *4.关闭IndexWriter
 6  */
 7 public class Update {
 8
 9     private IndexWriter indexWriter;
10
11     @Before
12     public void init() throws Exception {
13          indexWriter =
14                  new IndexWriter(FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath()),
15                         new IndexWriterConfig(new IKAnalyzer()));
16     }
17
18     @Test
19     public  void updateDocument() throws Exception {
20         Document document = new Document();
21
22         document.add(new TextField("name","更新后的文档",Field.Store.YES));;
23
24         indexWriter.updateDocument(new Term("name","spring"),document);
25
26         indexWriter.close();
27
28
29     }
30
31 }

索引库查询

1)使用Lucene提供Query子类

2)使用QueryParse解析查询表达式

Query

public class testRangeQuery{

    private IndexReader indexReader;

    private IndexSearcher indexSearcher;

    @Before
    public void init() throws Exception {
        indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath()));
        indexSearcher = new IndexSearcher(indexReader);
    }

    @Test
    public void testRangleQuery() throws Exception {

        Query query = LongPoint.newRangeQuery("size", 0l, 10000l);
        TopDocs topDocs = indexSearcher.search(query, 10);
        System.out.println("总记录数:"+topDocs.totalHits);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for(ScoreDoc doc:scoreDocs) {
            int docId = doc.doc;
            Document document = indexSearcher.doc(docId);
            System.out.println(document.get("name"));
            System.out.println(document.get("path"));
            System.out.println(document.get("size"));
            System.out.println(document.get("content"));
            System.out.println("----------------------");

        }
        indexReader.close();
    }

}

QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询

 1 /**
 2  *1.创建QueryParser对象,两个参数
 3  *            参数一,默认搜索域 。 第二 ,分析器对象
 4  *2.使用QueryPaser对象创建一个Query对象
 5  *3.执行查询
 6  *
 7  */
 8 public class Paser  {
 9
10     private IndexReader indexReader;
11
12     private IndexSearcher indexSearcher;
13
14     @Before
15     public void init() throws Exception {
16         indexReader = DirectoryReader.open(FSDirectory.open(new File("D:\\lucene\\demo\\index").toPath()));
17         indexSearcher = new IndexSearcher(indexReader);
18     }
19
20     @Test
21     public void testQueryParser() throws Exception {
22
23         //创建queryparser对象
24         //第一个参数默认搜索的域
25         //第二个参数就是分析器对象
26         QueryParser queryParser = new QueryParser("content", new IKAnalyzer());
27         Query query = queryParser.parse("Lucene是java开发的");
28         //执行查询
29         printResult(query, indexSearcher);
30     }
31
32     private void printResult(Query query, IndexSearcher indexSearcher) throws Exception {
33         //执行查询
34         TopDocs topDocs = indexSearcher.search(query, 10);
35         //共查询到的document个数
36         System.out.println("查询结果总数量:" + topDocs.totalHits);
37         //遍历查询结果
38         for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
39             Document document = indexSearcher.doc(scoreDoc.doc);
40             System.out.println(document.get("filename"));
41             System.out.println(document.get("content"));
42             System.out.println(document.get("path"));
43             System.out.println(document.get("size"));
44         }
45         //关闭indexreader
46         indexSearcher.getIndexReader().close();
47     }
48 }

原文地址:https://www.cnblogs.com/quyangyang/p/11314646.html

时间: 2024-10-10 22:02:20

Lucene01的相关文章

Lucene-01:创建索引

我们在D盘下建一个文件夹叫lucene,lucene内再建两个文件夹,一个叫example,一个叫index01.example文件夹下三个txt文件,a.txt内容为hello java,b.txt内容为hello lucene,c.txt内容为hello hadoop. package com.amazing; import java.io.File; import java.io.FileReader; import java.io.IOException; import org.apac

【Lucene】Apache Lucene全文检索引擎架构之入门实战

Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供.Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻.在Java开发环境里Lucene是一个成熟的免费开源工具.就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库.--<百度百科> 这篇博文主要从两个方面出发,首先介绍一下Lucene中的全文搜索原理,其次通过程序示例来展现如何使用Lucene.关于全文搜索原理部分我上网搜索了一下,也看了好几篇文章,最后在写这篇文

Lucene系列:(4)LuceneUtils之同步分页

1.工具类LuceneUtils LuceneUtils.java package com.rk.lucene.utils; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.apache.commons.beanutils.BeanUtils; import 

Lucene全文检索引擎

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersi

Lucene初体验——Hello Word实现

1.创建索引 1 /** 2 * 建立索引 3 */ 4 public void index(){ 5 IndexWriter writer=null; 6 try { 7 //1.创建Directory 8 //Directory directory=new RAMDirectory();//建立在内存中 9 Directory directory=FSDirectory.open(new File("D:/lucene/lucene01"));//创建在硬盘上 10 //2.创建I

Lucene_Hello(示例)

(1)创建project (2)导入Lucene的核心包 (3)编写代码建立索引 /lucene01/src/cn/hk/lucene/TestIndex.java: 1 package cn.hk.lucene; 2 3 import java.io.File; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import org.apache.lucene.analysis.standard.StandardAnaly