03. lucene索引库的维护

lucene索引库的维护

一、常用的域 field 的使用

1). 关键名词

  1. 是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
  2. 是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。比如:商品名称、商品简介分析后进行索引,订单号、身份证号不用分析但也要索引,这些将来都要作为查询条件。
  3. 是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取,比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。

是否存储的标准:是否要将内容展示给用户

2). 各个域的比较

Field类 数据类型 Analyzed是否分析 Indexed是否索引 Stored是否存储 说明
StringField(FieldName, FieldValue,Store.YES或者Store.NO)) 字符串 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.YES或者Store.NO)或TextField(FieldName, reader) 字符串 或 流 Y Y Y或N 如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.

二、添加文档

添加文档和创建索引库的步骤如出一辙,注意:不同的文档是可以有不同的域的! 存储不存储是不影响查询的

// 创建一个IndexWriter对象,需要使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));


// 读取磁盘上需要添加的文件
File file = new File("F:\\03Web开发\\03_lucene\\02.参考资料\\searchsource\\spring.txt");

// 创建一个Docunment对象
Document document = new Document();

// 向document中添加域
document.add(new TextField("filename", file.getName(), Field.Store.YES));
document.add(new TextField("contect", FileUtils.readFileToString(file, "utf-8"), Field.Store.YES));
document.add(new StoredField("size", FileUtils.sizeOf(file)));

// 将文档写入索引库
indexWriter.addDocument(document);

// 关闭索引库
indexWriter.close();

三、删除索引库

1). 删除所有文档对象 Document

// 创建一个IndexWriter对象,这里使用IKAnalyzer作为分析器
IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 删除全部文档
indexWriter.deleteAll();

// 关闭索引库
indexWriter.close();

2). 根据查询针对性删除文档对象 Document

IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 将name域中包含有 php 的文档对象Document删除
indexWriter.deleteDocuments(new Term("name", "php"));

indexWriter.close();

四、更新索引库

更新的原理是 先删除 后添加

IndexWriter indexWriter = new IndexWriter(
        FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath()),
        new IndexWriterConfig(new IKAnalyzer()));

// 创建一个新的文档用于替换被查询的文档集合
Document document = new Document();

// 向文档中添加域
document.add(new TextField("name", "filename", Field.Store.YES));
document.add(new TextField("context", "file content", Field.Store.YES));

// 更新替换操作
// 第一个为查询被替换的文档集合,第二个参数为一个文档
indexWriter.updateDocument(new Term("name"), document);

/* 下面的方式的第二个参数可以写一个可迭代的集合
indexWriter.updateDocuments(new Term("name"), documents);
*/

// 关闭索引库
indexWriter.close();

五、索引库的查询

1). TermQuery(Query的子类)

根据关键字进行查询,需要执行查询的域以及要查询的关键字
全文检索lucene创建索引库

2). 范围查询(Query的子类)

范围查询,针对 LongPoint

//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());

//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);

//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

//4. 创建一个Query对象,rangeQuery, 第一个为域,第二、三个参数为范围
Query query = LongPoint.newRangeQuery("size", 0L, 100L);

//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);

//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);

//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
    // 取文档id
    int docId = doc.doc;

    // 根据id获取文档对象
    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("--------------------------------");
}

//9. 关闭IndexReader对象。
indexReader.close();

3). QueryParser 进行查询

可以对要查询的内容先分词,然后基于分词的结果进行查询。

  1. 需要添加一个jar包:lucene-queryParser-7.4.0.jar
  2. maven坐标
<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>7.4.0</version>
</dependency>
  1. 查询示例
//1. 创建一个Director对象,指定索引库的位置
Directory directory = FSDirectory.open(new File("E:\\lucene_repository\\rep_01").toPath());

//2. 创建一个IndexReader对象
IndexReader indexReader = DirectoryReader.open(directory);

//3. 创建一个IndexSearcher对象,构造方法中的参数indexReader对象。
IndexSearcher indexSearcher = new IndexSearcher(indexReader);

//4. 创建一个QueryParser对象,两个参数
// 参数1:默认搜索域,参数2:分析器对象
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());

Query query = queryParser.parse("lucene是一个Java开发的全文检索工具包");

//5. 执行查询,得到一个TopDocs对象
// 参数1: 查询对象; 参数2:限制查询结果返回的最大记录数,
TopDocs topDocs = indexSearcher.search(query, 10);

//6. 取查询结果的总记录数
System.out.println("查询的总记录数:" + topDocs.totalHits);

//7. 取文档列表
ScoreDoc[] scoreDocs = topDocs.scoreDocs;

//8. 打印文档中的内容
for (ScoreDoc doc : scoreDocs) {
    // 取文档id
    int docId = doc.doc;

    // 根据id获取文档对象
    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("--------------------------------");
}

//9. 关闭IndexReader对象。
indexReader.close();

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容