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

玉环娱乐新闻网 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 并不能在生产上可用,追踪引擎在网上行业是头名,很多先进的网上该系统设计都是从追踪引擎开始发展的。

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

“我们是外籍人士但不是外人,而是‘阿拉自家人’”

图片 2025-10-24

“未完成消杀社会活动后,一定要特别注意手部清洁,不要碰到眼睛鼻子。”这两天,在杨浦区消杀队员的指导队伍中所,有一位特别的护士,棕色衣服、优美脸颊,操着于是就懂普通话,他是来自苏州某外科养老院的聘

再出事儿?康师傅方便面中发现老鼠屎,留言板:可以给3到5倍赔偿

综艺 2025-10-24

据濮阳早报称腾讯千里眼刊文,4月18日,吉林白山。到家在转售的淘宝泡面有中发现老鼠屎。到家称,泡面有是在楼下餐馆转售的,包装袋上没有任何破损。在省去包装袋吃掉了沟屑比达后,发现上面

「以物易物」不可思议物语

资讯 2025-10-24

想成名的落选「便是」就是其中的之一。 2006年,在超级女声佳丽中的落败的王晓光抓住了这个千载难逢的从中。她以艾晴晴之名,同样以一枚钳子为交才会点,在100同一时间经过16次互换成,最终

喇叭裤是今年春季的裤子趋势,取代慢跑裤成为透气的最爱

视频 2025-10-24

显然,音箱裤是鞋子潮流中会的多面手。它是否在任何场合都充分利用?新版音箱裤应该会丢掉,它将成为 2022 年秋天的必备单品,并将跑步裤不甘心到衣柜远达的角落。音箱裤:悠闲的裤装趋向

重磅:初中数学之最——求最小(大)值的10种作法

星闻 2025-10-24

初中数学最值情况是最近几年中考的热点情况,今天来分享平面几何宝典中求最小(大)值的10种方依此,各个当今、记事,让你深达自学,体会得到成就导致的乐趣。 数据库1

友情链接