几百行编码完成百度搜索引擎

玉环娱乐新闻网 2025-08-19

ndexUtil getInstance() { return SingletonHolder.luceneUtil; } private static class SingletonHolder { public final static LuceneIndexUtil luceneUtil = new LuceneIndexUtil(); } private LuceneIndexUtil() { this.initLuceneUtil(); } private void initLuceneUtil() { try { Directory dir = FSDirectory.open(Paths.get(INDEX_PATH)); Analyzer analyzer = new StandardAnalyzer(); IndexWriterConfig iwc = new IndexWriterConfig(analyzer); writer = new IndexWriter(dir, iwc); } catch (IOException e) { log.error("create luceneUtil error"); if (null != writer) { try { writer.close(); } catch (IOException ioException) { ioException.printStackTrace(); } finally { writer = null; } } } } /** * 录入单个PDF * * @param doc PDF信息 * @throws IOException IO 出现异常 */ public void addDoc(Document doc) throws IOException { if (null != doc) { writer.addDocument(doc); writer.commit(); writer.close(); } } /** * 录入单个实质上 * * @param model 单个实质上 * @throws IOException IO 出现异常 */ public void addModelDoc(Object model) throws IOException { Document document = new Document(); List fields = luceneField(model.getClass()); fields.forEach(document::add); writer.addDocument(document); writer.commit(); writer.close(); } /** * 录入实质上一览表 * * @param objects 最非常简单一览表 * @throws IOException IO 出现异常 */ public void addModelDocs(List objects) throws IOException { if (CollectionUtils.isNotEmpty(objects)) { List docs = new ArrayList<>(); objects.forEach(o -> { Document document = new Document(); List fields = luceneField(o); fields.forEach(document::add); docs.add(document); }); writer.addDocuments(docs); } } /** * 清扫所有PDF * * @throws IOException IO 出现异常 */ public void delAllDocs() throws IOException { writer.deleteAll(); } /** * 录入PDF一览表 * * @param docs PDF一览表 * @throws IOException IO 出现异常 */ public void addDocs(List docs) throws IOException { if (CollectionUtils.isNotEmpty(docs)) { long startTime = System.currentTimeMillis(); writer.addDocuments(docs); writer.commit(); log.info("共录入{}个 Document,共耗时{} 毫秒", docs.size(), (System.currentTimeMillis() - startTime)); } else { log.warn("录入一览表为空"); } } /** * 根据实质上 class 普通人获取队列类型,开展 lucene Field 队列拓扑 * * @param modelObj 实质上 modelObj 普通人 * @return 队列拓扑一览表 */ public List luceneField(Object modelObj) { Map classFields = ReflectionUtils.getClassFields(modelObj.getClass()); Map classFieldsValues = ReflectionUtils.getClassFieldsValues(modelObj); List fields = new ArrayList<>(); for (String key : classFields.keySet()) { Field field; String dataType = StringUtils.substringAfterLast(classFields.get(key).toString(), "."); switch (dataType) { case "Integer": field = new IntPoint(key, (Integer) classFieldsValues.get(key)); break; case "Long": field = new LongPoint(key, (Long) classFieldsValues.get(key)); break; case "Float": field = new FloatPoint(key, (Float) classFieldsValues.get(key)); break; case "Double": field = new DoublePoint(key, (Double) classFieldsValues.get(key)); break; case "String": String String = (String) classFieldsValues.get(key); if (StringUtils.isNotBlank(string)) { if (string.length() <= 1024) { field = new StringField(key, (String) classFieldsValues.get(key), Field.Store.YES); } else { field = new TextField(key, (String) classFieldsValues.get(key), Field.Store.NO); } } else { field = new StringField(key, StringUtils.EMPTY, Field.Store.NO); } break; default: field = new TextField(key, JsonUtils.obj2Json(classFieldsValues.get(key)), Field.Store.YES); break; } fields.add(field); } return fields; } public void close() { if (null != writer) { try { writer.close(); } catch (IOException e) { log.error("close writer error"); } writer = null; } } public void commit() throws IOException { if (null != writer) { writer.commit(); writer.close(); } }}

有了物件类,我们便写一个 demo 来开展原始数据的录入

import java.util.ArrayList;import java.util.List;/** *
* Function:
* Author:@author Silence
* Date:2020-10-17 21:08
* Desc:
*/public class Demo { public static void main(String[] args) { LuceneIndexUtil luceneUtil = LuceneIndexUtil.getInstance(); List articles = new ArrayList<>(); try { //录入原始数据 ArticleModel article1 = new ArticleModel(); article1.setTitle("Java 社不会心理学该系统设计"); article1.setAuthor("鸭血粉丝"); article1.setContent("这是一篇给大家简介 Lucene 的该系统设计文中,必定点赞评论投递!!!"); ArticleModel article2 = new ArticleModel(); article2.setTitle("社不会心理学该系统设计"); article2.setAuthor("鸭血粉丝"); article2.setContent("此处省略两千字..."); ArticleModel article3 = new ArticleModel(); article3.setTitle("Java 社不会心理学该系统设计"); article3.setAuthor("鸭血粉丝"); article3.setContent("最后邀请你重新加入我们的知识潘朵拉,Today is big day!"); articles.add(article1); articles.add(article2); articles.add(article3); luceneUtil.addModelDocs(articles); luceneUtil.commit(); } catch (Exception e) { e.printStackTrace(); } }}

上面的 content 主旨可以自行开展替换,阿粉这边避免明石用字的嫌疑就不附上了。

展示

开始运行终止下一场,我们用过 Lucene 的仿真物件 luke 来查看下录入的原始数据主旨,浏览下一场解压我们可以碰到有.bat 和 .sh 两个剧本,根据自己的该系统开展开始运行就好了。阿粉这边是 mac 用的是 sh 剧本开始运行,开始运行后打开设为的录入目录亦可。

luke 在 GitHub 上面有,但是浏览很慢,阿粉这边通过海外服务器浏览原地,并YouTube的百度网盘中所了,公众号回复【luke】获取。

踏入下一场,我们可以碰到下图显示的主旨,选取 content 点击 show top items 可以碰到右方的录入原始数据,这里根据分词器的多种不同,录入的结果是不一样的,阿粉这里使用的分词器就是国际标准的分词器,恰巧们可以根据自己的要求选取适当自己的分词器亦可。

追踪原始数据

原始数据已经录入并成功了,接原地我们就需根据条件开展原始数据的追踪了,我们始创一个 LuceneSearchUtil.java 来操作原始数据。

import org.apache.commons.collections.MapUtils;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.index.DirectoryReader;import org.apache.lucene.queryparser.classic.QueryParser;import org.apache.lucene.search.*;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;import org.springframework.beans.factory.annotation.Value;import java.io.IOException;import java.nio.file.Paths;import java.util.Map;public class LuceneSearchUtil { private static String INDEX_PATH = "/opt/lucene/demo"; private static IndexSearcher searcher; public static LuceneSearchUtil getInstance() { return LuceneSearchUtil.SingletonHolder.searchUtil; } private static class SingletonHolder { public final static LuceneSearchUtil searchUtil = new LuceneSearchUtil(); } private LuceneSearchUtil() { this.initSearcher(); } private void initSearcher() { Directory directory; try { directory = FSDirectory.open(Paths.get(INDEX_PATH)); DirectoryReader reader = DirectoryReader.open(directory); searcher = new IndexSearcher(reader); } catch (IOException e) { e.printStackTrace(); } } public TopDocs searchByMap(Map queryMap) throws Exception { if (null == searcher) { this.initSearcher(); } if (MapUtils.isNotEmpty(queryMap)) { BooleanQuery.Builder builder = new BooleanQuery.Builder(); queryMap.forEach((key, value) -> { if (value instanceof String) { Query queryString = new PhraseQuery(key, (String) value);// Query queryString = new TermQuery(new Term(key, (String) value)); builder.add(queryString, BooleanClause.Occur.MUST); } }); return searcher.search(builder.build(), 10); } return null; }}

在 demo.java 中所提高追踪字符如下:

//浏览原始数据 Map map = new HashMap<>(); map.put("title", "Java 社不会心理学该系统设计");// map.put("title", "社不会心理学该系统设计");// map.put("content", "最"); LuceneSearchUtil searchUtil = LuceneSearchUtil.getInstance(); TopDocs topDocs = searchUtil.searchByMap(map); System.out.println(topDocs.totalHits);

开始运行结果如下,说明追踪到了两条。

通过仿真物件我们可以碰到 title 为"Java 社不会心理学该系统设计"或许是有两条记录下来,而且我们也确认只插入了两条原始数据。注意这里如果根据其他字符去浏览可能浏览不出来,因为阿粉这里的分词器使用的是选项的分词器,恰巧可以根据自身的状况使用相应的分词器。

至此我们可以录入和追踪原始数据了,不过这还是非常简单的初阶操作,对于多种不同类型的队列,我们需可用多种不同的浏览模式,而且根据该系统的特性我们需可用特定的分词器,选项的国际标准分词器不一定符合我们的可用故事情节。而且我们录入原始数据的时候也需根据队列类型开展多种不同 Field 的设定。上面的例子只是 demo 并不能在生产上可用,追踪引擎在网上行业是头名,很多先进的网上该系统设计都是从追踪引擎开始发展的。

产后老是脱发怎么办
奢批一件代发
铝型材
女性整形
小儿咳嗽药
经常拉稀
吃什么药治疗风热感冒咳嗽
退烧
相关阅读

“聚会门”调查报告发布后 民调显示59%的英国人认为首相应离任

图片 2025-08-23

据苏格兰媒体25日报道,苏格兰布莱尔“派对道门”事件调查公布后,舆观调查网进行时的一项快速民意调查发现,59%的苏格兰人认为前首相亚当斯应辞职。调查发现,59%的不感兴趣调查者问到,前首相应离

喜马拉雅画出虚设年轮

时尚 2025-08-23

出体育原先闻凭借过人的音乐厅能力崭露头角。曾音乐厅《斗破续篇》有声剧中的啼玖即是其里之一,在当年涉足刺耳创作音乐行业先前,她曾是商丘焦作城北养老院的一名护士,怀揣着对有声素材的热忱,啼玖并不需要辞去文

颖泰生物资产减值惹来北交所首份年报问询函:将积极回应财务“喝水”质疑

八卦 2025-08-23

说了几种财政造假的方式。他所述,如果苍增本息账款,企业只是上半年富人,本息款收不返来;如果是苍列开发成本,把钱转出去做到佣金,一般都会在帐单上动手脚,苍挂帐单;如果是苍持续增长期金融机构,一般

山东主教练面临考验,管理层考虑换新领队,宫鲁鸣或将改派巩晓彬

图片 2025-08-23

面的赛季,直到现在的滑落确有来得大。 另外宫鲁鸣作为队长组层面的最主要成员,或许四人的有为特意也好,在门将的移除,以及在重用哪名门将的这个决策上面,都是长期存在非常大情况的。该重用的

比方说是系统为什么有的叫OS有的叫UI

星闻 2025-08-23

大家不对确信如今APP该系统虽然主要分iOS和格斯两大阵营,但如果从叫法的单词上来区别于的话说是是可分OS和UI。那么,你不对想过为什么有些APP的该系统单词是OS?有些该系统的单词是UI呢?他

友情链接