只用了几百行代码写的百度搜索引擎,你看咋样?,web开发难点

writer.close();
} catch (IOException ioException) {
ioException.printStackTrace();
} finally {
writer = null;
}
}
}
}

/**

  • 索引单个文档
  • @param doc 文档信息
  • @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);
    }
    }

/**

  • 清除所有文档
  • @throws IOException IO 异常
    */
    public void delAllDocs() throws IOException {
    writer.deleteAll();
    }

/**

  • 索引文档列表
  • @param docs 文档列表
  • @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<String, Object> classFields = ReflectionUtils.getClassFields(modelObj.getClass());
    Map<String, Object> 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 脚本运行,运行后打开设置的索引目录即可。

进入过后,我们可以看到下图显示的内容,选择 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<String, Object> 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;
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

javascript是前端必要掌握的真正算得上是编程语言的语言,学会灵活运用javascript,将对以后学习工作有非常大的帮助。掌握它最重要的首先是学习好基础知识,而后通过不断的实战来提升我们的编程技巧和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。

资料领取方式:点击这里免费领取前端全套学习资料

css源码pdf

JavaScript知识点
和逻辑思维。这一块学习是持续的,直到我们真正掌握它并且能够灵活运用它。如果最开始学习一两遍之后,发现暂时没有提升的空间,我们可以暂时放一放。继续下面的学习,javascript贯穿我们前端工作中,在之后的学习实现里也会遇到和锻炼到。真正学习起来并不难理解,关键是灵活运用。

资料领取方式:点击这里免费领取前端全套学习资料

[外链图片转存中…(img-I2mjheZY-1712320542088)]

[外链图片转存中…(img-Q01Jg2ln-1712320542088)]

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
E桶金搜索引擎系统(包含多线程客户端蜘蛛系统) V1.6 版发布! E桶金搜索引擎 特别适用于超大、中型信息门户、业门户、电子商务等网站使用。 它是一款真正意义上的搜索引擎:具有自己的蜘蛛、分词、索引、搜索等全套功能。 而且所有功能全部基于web页面完成,您只需要购买一款支持asp.net的虚拟主机就能完成本程序的部署,网站轻松上线。 本程序具有毫秒级高速搜索, 搜索结果相关度排序 。多关键词搜索、超长词条搜索、关键词高亮显示。 该程序为ASP.NET2.0版本程序,只要空间支持asp.net2.0即可。 需要确保iis的默认文档中包含default.aspx 演示地址:http://so.12ym.com 官方网址:http://www.12ym.com/3/111/ 技术支持:http://bbs.12ym.com/ 后台管理地址:/admin/default.aspx 默认帐号和密码均为:etongjin 本程序包中的Spider.rar文件是客户端蜘蛛插件,用于多线程快速索引网站,并抓取快照。 本程序包中的MsSql.rar文件为MsSql数据库版本附加文件包,如果您想使用sql版本,参照mssql增值包中的说明。 注意:本程序的商业授权分两种版本:Access版本和MsSql版本,如果您的授权是Access版本,那么升级为MsSql版本后,将变为MsSql免费版本,如果想升级为MsSql商业版本,请联系E桶金客服。 本系统目前只支持网站根目录浏览,不能放到虚拟目录或者子文件夹中! 如果您想购买E桶金搜索引擎,可以联系销售客服QQ。 销售客服QQ:83498254,178301967 E桶金软件(http://www.etongjin.com),助您博得人生的第一桶金 ! 2011.06.01升级(1.6版本)的主要内容如下: 1.提供两种蜘蛛客户端索引和网站索引进合并的策略 2.优化编码识别规则,大幅件减少搜索日志乱码现象 3.后台可批量删除某一域名下的所有搜引文件的功能! 4.可过滤某一ip的搜索记录,避免数据库迅速膨胀 5.将广告内容的字数限制由100个字符增长到128个字符 6.升级优化客户端蜘蛛的部分功能:修正入口地址设置中屏蔽的url关键词设置后无效的问题;修正定时更新,间隔更新设置后,按钮无法提交的问题;蜘蛛程序每执一阶段采集任务后,自动释放cpu和内存,避免蜘蛛一直执会挂死。 2011.05.18升级(1.51版本) 1.5版升级的主要内容如下: 1.全新规划系统架构,彻底分离数据访问层,推出Access和MS SQL两个版本。(非常重要) 2.增加百宝箱功能,可以像百度开放平台一样轻松地在自己的搜索中增加自己特有的应用,如:万年历、时间、在线汇率等; 3.推广用户增加保存公司名称和网址的功能。(重要) 4.优化前台页面显示。 2011.02.18升级(1.1版本) 1.1版升级的主要内容如下: 1.推广中心集成支付宝支付功能,可以直接在线充值投放竞价广告。(非常重要) 2.增加记录百度、Google等搜索引擎记录的功能,并在搜索日志和广告点击记录中过滤蜘蛛的爬日志。 3.后台的“广告点击记录”、“用户贡献列表”、“搜索日志列表”、“蜘蛛爬列表”均增加“删除全部记录”的按钮,当数据库较大时可选择一次性清理这些数据。(重要) 4.对推广中心和后台管理界面的细节和样式进优化。(重要) 2011.01.12升级(1.0 Beta版本) 1.0版升级的主要内容如下: 1.增加客户端蜘蛛功能,多线程抓取快照,建立索引,更加高效、稳定。(重要) 2.初步完成插件机制,为以后的程序功能扩展提供基础。(重要) 3.对搜索列表页面进SEO处理,避免百度、Google等搜索引擎陷入链接陷阱。 2010.12.17升级(0.95版本) 0.95版升级的主要内容如下: 1.提高系统稳定性:优化蜘蛛抓取网页时索引建立的方式,避免因服务器异常,导致整站索引损坏的问题;优化一些蜘蛛抓取的容错功能。(重要) 2.完善搜索关键词竞价广告系统,使广告匹配更精准;增加竞价价格查询;并修正关键词广告删除后,个别时候仍会扣掉广告主一些积分的bug。(重要) 3.完善索引系统:增加对页面meta标签中description属性的索引;修正个别页面会索引css或js代码的问题;修正后台有时无法删除索引的问题。 4.增加一些后台配置功能:自由设置当本站搜索不出结果时是否自动补充百度搜索结果;自由设置网站蜘蛛的名称;自由设置注册的推广用户是否需要审核。(重要) 2010.09.10升级(0.92版本) 0.92版升级的主要内容如下:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值