Lucene8学习:创建索引

1.1. 创建索引

示例:

  1 import org.apache.lucene.analysis.Analyzer;
  2 
  3 import org.apache.lucene.analysis.TokenStream;
  4 
  5 import org.apache.lucene.analysis.core.WhitespaceAnalyzer;
  6 
  7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
  8 
  9 import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
 10 
 11 import org.apache.lucene.document.Document;
 12 
 13 import org.apache.lucene.document.Field;
 14 
 15 import org.apache.lucene.document.StringField;
 16 
 17 import org.apache.lucene.document.TextField;
 18 
 19 import org.apache.lucene.index.DirectoryReader;
 20 
 21 import org.apache.lucene.index.IndexWriter;
 22 
 23 import org.apache.lucene.index.IndexWriterConfig;
 24 
 25 import org.apache.lucene.index.Term;
 26 
 27 import org.apache.lucene.queryparser.classic.ParseException;
 28 
 29 import org.apache.lucene.queryparser.classic.QueryParser;
 30 
 31 import org.apache.lucene.search.*;
 32 
 33 import org.apache.lucene.store.Directory;
 34 
 35 import org.apache.lucene.store.RAMDirectory;
 36 
 37 import org.apache.lucene.util.BytesRef;
 38 
 39 import org.junit.Assert;
 40 
 41 import org.junit.Before;
 42 
 43 import org.junit.Test;
 44 
 45 import org.wltea.analyzer.lucene.IKAnalyzer;
 46 
 47  
 48 
 49 import cn.lmc.myworld.common.lucene.LuceneUtils;
 50 
 51  
 52 
 53 import java.io.IOException;
 54 
 55 import java.io.StringReader;
 56 
 57  
 58 
 59 public class IndexSearchDemo {
 60 
 61     private Directory directory = new RAMDirectory();
 62 
 63     private String[] ids = {"1", "2"};
 64 
 65     private String[] teamname = {"fpx", "ig"};
 66 
 67     private String[] contents = {"涅槃队,凤凰涅槃,勇夺2019LOLS赛冠军!", "翻山队,登峰造极,翻过那座山夺得了2019LOLS赛冠军!"};
 68 
 69     private String[] players = {"doinb,tian,lwx,crisp,gimgoong", "rookie,jacklove,ning,baolan,theshy"};
 70 
 71     private IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
 72 
 73     private IndexWriter indexWriter;
 74 
 75  
 76 
 77     @Before
 78 
 79     public void createIndex() {
 80 
 81         try {
 82 
 83             indexWriter = new IndexWriter(directory, indexWriterConfig);
 84 
 85             for (int i = 0; i < 2; i++) {
 86 
 87                 Document document = new Document();
 88 
 89                 Field idField = new StringField("id", ids[i], Field.Store.YES);
 90 
 91                 Field teamnameField = new StringField("teamname", teamname[i], Field.Store.YES);
 92 
 93                 Field contentField = new TextField("content", contents[i], Field.Store.YES);
 94 
 95                 Field playersField = new StringField("players", players[i], Field.Store.YES);
 96 
 97                 document.add(idField);
 98 
 99                 document.add(teamnameField);
100 
101                 document.add(contentField);
102 
103                 document.add(playersField);
104 
105                 indexWriter.addDocument(document);
106 
107             }
108 
109             indexWriter.close();
110 
111         } catch (IOException e) {
112 
113             e.printStackTrace();
114 
115         }
116 
117     }
118 
119  
120 
121     @Test
122 
123     public void testTermQuery() throws IOException {
124 
125         Term term = new Term("id", "1");
126 
127         IndexSearcher indexSearcher = getIndexSearcher();
128 
129         TopDocs topDocs = indexSearcher.search(new TermQuery(term), 10);
130 
131         // 1)打印总记录数(命中数):类似于百度为您找到相关结果约100,000,000个
132 
133      long totalHits = topDocs.totalHits.value;
134 
135      System.out.println("查询(命中)总的文档条数:"+totalHits);
136 
137      // LOGGER.info("查询(命中)文档最大分数:"+topDocs.getMaxScore());
138 
139      // 2)获取指定的最大条数的、命中的查询结果的文档对象集合
140 
141      ScoreDoc[] scoreDocs = topDocs.scoreDocs;
142 
143      // 打印具体文档
144 
145      for (ScoreDoc scoreDoc : scoreDocs) {
146 
147 int doc = scoreDoc.doc;
148 
149 Document document = indexSearcher.doc(doc);  
150 
151 // 打印content字段的值
152 
153 System.out.println("id: "+document.get("id"));
154 
155 System.out.println("teamname: "+document.get("teamname"));
156 
157 System.out.println("content: "+document.get("content"));
158 
159 System.out.println("players: "+document.get("players"));
160 
161 }
162 
163 }
164 
165 }

先来一个例子测试一下,我们要关注下面几个主要的类:

  1. Directory
  2. IndexWriterConfig
  3. IndexWriter
  4. IndexSearcher
  5. TopDocs
  6. ScoreDoc
  7. Document
  8. Field

1.1.1. Directory

由于Lucene的索引是存储在文件系统上面的,因此要通过Directory这个类来实现索引的存储。经常使用到的是下面两个类:

FSDirectory:在文件系统上存储索引文件

RAMDirectory:在内存中暂存索引文件,适用少量索引,大量索引会出现频繁GC

1.1.2. IndexWriterConfig

该类主要用于配置Lucene的分词器。

1.1.3. IndexWriter

该类为Lucene的操作类,可以对索引进行增,删操作。这里可能就会有人问了,”改”和”查”呢?

注意一下:

IndexWriter是有”改”(更新)操作的,但是实现的原理是先删除,后重新插入。因此更新的时候数据必须齐全,不能够只能更新一个字段的情况,这样有可能会出现将其他字段数据清空的问题。

另外,Lucene的索引统一时间内只能有一个IndexWriter来操作,因此设计工具类的时候,IndexWriter尽量设计为单例模式。

至于”查”操作则由另一个类IndexSearcher实现。

1.1.4. IndexSearcher

该类就是用来查询索引库的索引的。

1.1.5. TopDocs

该类包含IndexSearcher.search()方法返回的具有较高评分的顶部文档

1.1.6. ScoreDoc

该类提供对TopDocs中每条搜索结果的访问接口

1.1.7. Document

Lucene的文档,也可以看作数据库中的一条记录。

1.1.8. Field

Field属于Document的一部分,可以重复。可以看作数据库中的字段。

1.1.8.1. Field的类型

名称

说明

IntPoint

对int型字段索引,只索引不存储 

FloatPoint

对float型字段索引,只索引不存储 

LongPoint

对long型字段索引,只索引不存储 

DoublePoint

对double型字段索引,只索引不存储 

BinaryDocValuesField

只存储不共享,例如标题类字段

NumericDocValuesField

存储long型字段,用于评分、排序和值检索,可存储值,但需要添加一个单独的StoredField实例

SortedDocValuesField

索引并存储,用于String类型的Field排序,需要在StringField后添加同名的SortedDocValuesField

StringField

只索引但不分词,所有的字符串会作为一个整体进行索引,例如通常用于country或id等

TextField

索引并分词,不包括term vectors

StoredField

存储Field的值,可以用 IndexSearcher.doc和IndexReader.document来获取存储的Field和存储的值

注意:

由于Lucene是没有时间格式的字段的,因此要存储时间,就要将时间转化成数据用数据格式的NumericDocValuesField(建议)存储。

1.1.8.2. Field.Store

new StringField("id", ids[i], Field.Store.YES);

看这个,可以看到创建索引的时候,每个Field后面都要加一个Field.Store.YES或者Field.Store.NO这两个又是干嘛的呢?

Field.Store.YES:表示会把这个域中的内容完全存储到文件中

Field.Store.NO:表示把这个域的内容不存储到文件中,但是可以被索引

原文地址:https://www.cnblogs.com/bestlmc/p/11865673.html