️ lucene索引自动创建

- 文章更新时,索引自动更新
- 搜索正文预览太少则不替换命中
- 引入hutool核心工具包

️ lucene索引自动创建

- 文章更新时,索引自动更新
- 搜索正文预览太少则不替换命中
This commit is contained in:
Suwen 2021-02-25 13:56:14 +08:00
parent 96739bf1cf
commit 8aebd59807
5 changed files with 127 additions and 32 deletions

View File

@ -227,6 +227,14 @@
<version>${lucene.version}</version>
</dependency>
<!-- hutool 核心工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
<version>5.5.9</version>
</dependency>
</dependencies>
<build>

View File

@ -8,6 +8,7 @@ import com.rymcu.forest.dto.ArticleDTO;
import com.rymcu.forest.lucene.model.ArticleLucene;
import com.rymcu.forest.lucene.service.LuceneService;
import com.rymcu.forest.lucene.service.UserDicService;
import com.rymcu.forest.lucene.util.ArticleIndexUtil;
import com.rymcu.forest.util.Utils;
import org.springframework.web.bind.annotation.*;
@ -34,6 +35,8 @@ public class LuceneSearchController {
@PostConstruct
public void createIndex() {
// 删除系统运行时保存的索引重新创建索引
ArticleIndexUtil.deleteAllIndex();
ExecutorService executor = Executors.newSingleThreadExecutor();
CompletableFuture<String> future =
CompletableFuture.supplyAsync(
@ -84,7 +87,10 @@ public class LuceneSearchController {
for (int i = 0; i < articleDTOList.size(); i++) {
temp = articleDTOList.get(i);
temp.setArticleTitle(subList.get(i).getArticleTitle());
if (subList.get(i).getArticleContent().length() > 10) {
// 内容中命中太少则不替换
temp.setArticlePreviewContent(subList.get(i).getArticleContent());
}
articleDTOList.set(i, temp);
}
page.addAll(articleDTOList);

View File

@ -25,14 +25,22 @@ public interface LuceneService {
*
* @param id
*/
void writeArticle(String id) throws Exception;
void writeArticle(String id);
/**
* 写入单个文章索引
*
* @param articleLucene
*/
void writeArticle(ArticleLucene articleLucene);
/**
* 更新单个文章索引
*
* @param id
*/
void updateArticle(String id) throws Exception;
void updateArticle(String id);
/**
* 删除单个文章索引

View File

@ -6,6 +6,7 @@ import com.rymcu.forest.lucene.lucene.IKAnalyzer;
import com.rymcu.forest.lucene.mapper.ArticleLuceneMapper;
import com.rymcu.forest.lucene.model.ArticleLucene;
import com.rymcu.forest.lucene.service.LuceneService;
import com.rymcu.forest.lucene.util.ArticleIndexUtil;
import com.rymcu.forest.lucene.util.SearchUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
@ -21,11 +22,13 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@ -82,39 +85,23 @@ public class LuceneServiceImpl implements LuceneService {
}
@Override
public void writeArticle(String id) throws Exception {
// TODO 做新增或更新判断
writeArticle(luceneMapper.getById(id), false);
public void writeArticle(String id) {
writeArticle(luceneMapper.getById(id));
}
@Override
public void updateArticle(String id) throws Exception {
writeArticle(luceneMapper.getById(id), false);
public void writeArticle(ArticleLucene articleLucene) {
ArticleIndexUtil.addIndex(articleLucene);
}
@Override
public void updateArticle(String id) {
ArticleIndexUtil.updateIndex(luceneMapper.getById(id));
}
@Override
public void deleteArticle(String id) {
try {
deleteIndex(id);
} catch (IOException e) {
e.printStackTrace();
}
}
private void writeArticle(ArticleLucene article, boolean create) throws Exception {
if (!create) {
deleteIndex(article.getIdArticle());
}
ArticleBeanIndex index = new ArticleBeanIndex(indexPath, 777);
index.indexDoc(article);
}
private void deleteIndex(String id) throws IOException {
int size = Objects.requireNonNull(new File(indexPath).listFiles()).length;
while (size-- >= 0) {
ArticleBeanIndex index = new ArticleBeanIndex(indexPath, size);
index.deleteDoc(id);
}
ArticleIndexUtil.deleteIndex(id);
}
/**
@ -147,7 +134,7 @@ public class LuceneServiceImpl implements LuceneService {
Highlighter highlighter = new Highlighter(htmlFormatter, new QueryScorer(query));
// 获取搜索的结果指定返回document返回的个数
// 默认搜索结果为显示第一页1000 可以优化
// TODO 默认搜索结果为显示第一页1000 可以优化
TopDocs results = SearchUtil.getScoreDocsByPerPage(1, 100, searcher, query);
ScoreDoc[] hits = results.scoreDocs;

View File

@ -0,0 +1,86 @@
package com.rymcu.forest.lucene.util;
import cn.hutool.core.io.FileUtil;
import com.rymcu.forest.lucene.model.ArticleLucene;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.StringField;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import java.io.IOException;
import java.util.Arrays;
/**
* 文章索引更新工具类
*
* @author suwen
*/
public class ArticleIndexUtil {
/** lucene索引保存目录 */
private static final String PATH = System.getProperty("user.dir") + "/lucene/index";
/** 系统运行时索引保存目录 */
private static final String INDEX_PATH =
System.getProperty("user.dir") + "/lucene/index/index777";
/** 删除所有运行中保存的索引 */
public static void deleteAllIndex() {
if (FileUtil.exist(INDEX_PATH)) {
FileUtil.del(INDEX_PATH);
}
}
public static void addIndex(ArticleLucene t) {
creatIndex(t);
}
public static void updateIndex(ArticleLucene t) {
deleteIndex(t.getIdArticle());
creatIndex(t);
}
/**
* 增加或创建单个索引
*
* @param t
* @throws Exception
*/
private static synchronized void creatIndex(ArticleLucene t) {
System.out.println("创建单个索引");
IndexWriter writer;
try {
writer = IndexUtil.getIndexWriter(INDEX_PATH, false);
Document doc = new Document();
doc.add(new StringField("id", t.getIdArticle() + "", Field.Store.YES));
doc.add(new TextField("title", t.getArticleTitle(), Field.Store.YES));
doc.add(new TextField("summary", t.getArticleContent(), Field.Store.YES));
writer.addDocument(doc);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/** 删除单个索引 */
public static synchronized void deleteIndex(String id) {
Arrays.stream(FileUtil.ls(PATH))
.forEach(
each -> {
if (each.isDirectory()) {
IndexWriter writer;
try {
writer = IndexUtil.getIndexWriter(each.getAbsolutePath(), false);
writer.deleteDocuments(new Term("id", id));
writer.forceMergeDeletes(); // 强制删除
writer.commit();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}