solr搜索引擎 搜索引擎 开源
- 软件开发
- 2023-08-13
- 91
大家好,关于solr搜索引擎很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于开源的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题...
大家好,关于solr搜索引擎很多朋友都还不太明白,不过没关系,因为今天小编就来为大家分享关于开源的知识点,相信应该可以解决大家的一些困惑和问题,如果碰巧可以解决您的问题,还望关注下本站哦,希望对各位有所帮助!
java如何实现搜索功能
先写具体的实现代码,具体的实现思路和逻辑写在代码之后。
搜索时用于排序的Bean
构造的搜索数据结构以及简单的搜索算法
[java]viewplaincopyprint?/***@Description:*/packagecn.lulei.search.engine;importjava.util.ArrayList;importjava.util.Collections;importjava.util.Comparator;importjava.util.HashMap;importjava.util.HashSet;importjava.util.List;importcn.lulei.search.engine.model.SortBean;publicclassSerachBase{//details存储搜素对象的详细信息,其中key作为区分Object的唯一标识privateHashMap<String,Object>details=newHashMap<String,Object>();//对于参与搜索的关键词,这里采用的稀疏数组存储,也可以采用HashMap来存储,定义格式如下//privatestaticHashMap<Integer,HashSet<String>>keySearch=newHashMap<Integer,HashSet<String>>();//HashMap中额key值相当于稀疏数组中的下标,value相当于稀疏数组在该位置的值privatefinalstaticintmaxLength=Character.MAX_VALUE;@SuppressWarnings("unchecked")privateHashSet<String>[]keySearch=newHashSet[maxLength];/***@Description:实现单例模式,采用InitializationonDemandHolder加载*@Author:lulei*@Date:2014-7-19*@Version:1.1.0*/privatestaticclasslazyLoadSerachBase{privatestaticfinalSerachBaseserachBase=newSerachBase();}/***这里把构造方法设置成私有为的是单例模式*/privateSerachBase(){}/***@return*@Date:2014-7-19*@Author:lulei*@Description:获取单例*/publicstaticSerachBasegetSerachBase(){returnlazyLoadSerachBase.serachBase;}/***@paramid*@return*@Date:2014-7-19*@Author:lulei*@Description:根据id获取详细*/publicObjectgetObject(Stringid){returndetails.get(id);}/***@paramids*@return*@Date:2014-7-19*@Author:lulei*@Description:根据ids获取详细,id之间用","隔开*/publicList<Object>getObjects(Stringids){if(ids==null||"".equals(ids)){returnnull;}List<Object>objs=newArrayList<Object>();String[]idArray=ids.split(",");for(Stringid:idArray){objs.add(getObject(id));}returnobjs;}/***@paramkey*@return*@Date:2014-7-19*@Author:lulei*@Description:根据搜索词查找对应的id,id之间用","分割*/publicStringgetIds(Stringkey){if(key==null||"".equals(key)){returnnull;}//查找//idTimes存储搜索词每个字符在id中是否出现HashMap<String,Integer>idTimes=newHashMap<String,Integer>();//ids存储出现搜索词中的字符的idHashSet<String>ids=newHashSet<String>();//从搜索库中去查找for(inti=0;i<key.length();i++){intat=key.charAt(i);//搜索词库中没有对应的字符,则进行下一个字符的匹配if(keySearch[at]==null){continue;}for(Objectobj:keySearch[at].toArray()){Stringid=(String)obj;inttimes=1;if(ids.contains(id)){times+=idTimes.get(id);idTimes.put(id,times);}else{ids.add(id);idTimes.put(id,times);}}}//使用数组排序List<SortBean>sortBeans=newArrayList<SortBean>();for(Stringid:ids){SortBeansortBean=newSortBean();sortBeans.add(sortBean);sortBean.setId(id);sortBean.setTimes(idTimes.get(id));}Collections.sort(sortBeans,newComparator<SortBean>(){publicintcompare(SortBeano1,SortBeano2){returno2.getTimes()-o1.getTimes();}});//构建返回字符串StringBuffersb=newStringBuffer();for(SortBeansortBean:sortBeans){sb.append(sortBean.getId());sb.append(",");}//释放资源idTimes.clear();idTimes=null;ids.clear();ids=null;sortBeans.clear();sortBeans=null;//返回returnsb.toString();}/***@paramid*@paramsearchKey*@paramobj*@Date:2014-7-19*@Author:lulei*@Description:添加搜索记录*/publicvoidadd(Stringid,StringsearchKey,Objectobj){//参数有部分为空,不加载if(id==null||searchKey==null||obj==null){return;}//保存对象details.put(id,obj);//保存搜索词addSearchKey(id,searchKey);}/***@paramid*@paramsearchKey*@Date:2014-7-19*@Author:lulei*@Description:将搜索词加入到搜索域中*/privatevoidaddSearchKey(Stringid,StringsearchKey){//参数有部分为空,不加载//这里是私有方法,可以不做如下判断,但为了设计规范,还是加上if(id==null||searchKey==null){return;}//下面采用的是字符分词,这里也可以使用现在成熟的其他分词器for(inti=0;i<searchKey.length();i++){//at值相当于是数组的下标,id组成的HashSet相当于数组的值intat=searchKey.charAt(i);if(keySearch[at]==null){HashSet<String>value=newHashSet<String>();keySearch[at]=value;}keySearch[at].add(id);}}}测试用例:
[java]viewplaincopyprint?/***@Description:*/packagecn.lulei.search.engine.test;importjava.util.List;importcn.lulei.search.engine.SerachBase;publicclassTest{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSerachBaseserachBase=SerachBase.getSerachBase();serachBase.add("1","你好!","你好!");serachBase.add("2","你好!我是张三。","你好!我是张三。");serachBase.add("3","今天的天气挺好的。","今天的天气挺好的。");serachBase.add("4","你是谁?","你是谁?");serachBase.add("5","高数这门学科很难","高数确实很难。");serachBase.add("6","测试","上面的只是测试");Stringids=serachBase.getIds("你的高数");System.out.println(ids);List<Object>objs=serachBase.getObjects(ids);if(objs!=null){for(Objectobj:objs){System.out.println((String)obj);}}}}测试输出结果如下:
5,3,2,1,4,高数确实很难。今天的天气挺好的。你好!我是张三。你好!你是谁?
这样一个简单的搜索引擎也就算是完成了。
问题一:这里面的分词采用的是字符分词,对汉语的处理还是挺不错的,但是对英文的处理就很弱。
改进方法:采用现在成熟的分词方法,比如IKAnalyzer、StandardAnalyzer等,这样修改,keySearch的数据结构就需要做下修改,可以修改为privateHashMap<String,String>[]keySearch=newHashMap[maxLength];其中key存储分的词元,value存储唯一标识id。
问题二:本文实现的搜索引擎对词元并没有像lucene设置权重,只是简单的判断词元是否在对象中出现。
改进方法:暂无。添加权重处理,使数据结构更加复杂,所以暂时没有对其做处理,在今后的文章中会实现权重的处理。
在SerachBase类中设置details和keySearch两个属性,details用于存储Object的详细信息,keySearch用于对搜索域做索引。details数据格式为HashMap,keySearch的数据格式为稀疏数组(也可以为HashMap,HashMap中额key值相当于稀疏数组中的下标,value相当于稀疏数组在该位置的值)。
对于details我就不做太多的介绍。
keySearch中数组下标(如用HashMap就是key)的计算方法是获取词元的第一个字符int值(因为本文的分词采用的是字符分词,所以一个字符就是一个词元),该int值就是数组的下标,相应的数组值就是Object的唯一标识。这样keySearch的数据结构就如下图
因此想添加新纪录的时候只需要调用add方法即可。
对于搜索的实现逻辑和上面的keySearch类似。对于id的搜索直接使用HashMap的get方法即可。对于搜索词的一个搜索,整体的过程也是采用先分词、其次查询、最后排序。当然这里面的分词要和创建采用的分词要一致(即创建的时候采用字符分词,查找的时候也采用字符分词)。
在getIds方法中,HashMap<String,Integer>idTimes=newHashMap<String,Integer>();idTimes变量用来存储搜索词中的词元有多少个在keySearch中出现,key值为唯一标识id,value为出现的词元个数。HashSet<String>ids=newHashSet<String>();ids变量用来存储出现的词元的ids。这样搜索的复杂度就是搜索词的词元个数n。获得包含词元的ids,构造SortBean数组,对其排序,排序规则是出现词元个数的降序排列。最后返回ids字符串,每个id用","分割。如要获取详细信息再使用getObjects方法即可。
为什么阿里不做搜索引擎
阿里是一直在做搜索引擎的,只不过阿里做搜索不叫阿里搜索,但是这并不代表阿里就没有做搜索引擎,比如神马搜索、夸克搜索(夸克浏览器自带搜索引擎)、比如针对性的淘宝商品搜索,1688货源搜索。其实阿里巴巴一直在搜索领域深耕,只不过由于入局时间更晚,技术和内容积累不够,所以阿里的搜索并没运作达到百度一样的知名度而已。
百度的搜索的领先优势在搜索领域的入局时间上,百度是国内最早做中文搜索产品之一的,并且以绝对的优势统治了PC的搜索市场十多年,谷歌退出中国之后,百度就占据了绝对的优势。先入为主的思想,几乎让百度成了搜索的代称,"百度一下,你就知道"这句广告词也已经非常的深入人心了。所以想要另一个产品快速的去替代是非常困难的。就像虽然有很多的挑战者,但是腾讯一直占据了社交领域的优势,阿里占据了电商的优势。如果对于搜索没有革命性的改变,先要撼动百度的地位也是非常的困难的。
百度拥有巨大的内容积累。如果搜索仅仅是把用户带到另一个网站,那么这个搜索引擎就比较容易替代。而百度自身拥有大量的内容积累,百度百科积累了大量的百科词条,百度文库积累了大量的文档资源,百度图片是最大的中文图片库,百度知道是最大的中文问答社区。想要成为百度的替代品,还要有强大的资源的积累。
搜索市场阿里的进击阿里在搜索领域也是一直在发展的,而且也是取得一定成绩的,只不过想要能达到百度的水平还需要很长的路要走。比如神马搜索已经发展了很长的时间,目前也取得了不错的市场份额。阿里的优势是阿里是将搜索引擎融入到自家的浏览器产品中,比如UC浏览器、夸克浏览器。而浏览器作为重要的上网入口,一旦占据了这个优势,那么搜索引擎自然而然的就做起来了。
这也是百度目前面临的困境,在PC时代,百度几乎是上网的入口,而移动互联网时代,百度却有些掉队了,移动互联网给百度留下来的入口约来越少,阿里开始做搜索、头条也开始做搜索、搜狗也在后面穷追猛打,百度的日子并不好过
PC时代我们最常见的操作就是打开浏览器用百度搜索,而移动互联网时代,我们通常更喜欢到专门的软件去观看搜索,比如去知乎搜索一些问题的答案,去头条搜索一些实时新闻动态,去抖音搜索短视频,并且很多网站现在内容也限制百度去爬取,比如微信公众号的内容以及头条的内容百度就搜索不到,而使用搜狗搜索就可以进行搜索公众号内容,使用头条搜索就可以搜索到头条的内容。即使很多内容被百度搜索到了,也会提示跳转到app观看。
被限制的滋味不好受,于是百度推出了百家号来对标头条,推出好看视频、全民小视频对标西瓜视频、抖音快手。去做自己的百度APP增强百度的流量入口。
es和solr使用场景对比
1.es和solr都是搜索引擎,但在使用场景上有所不同。2.es(Elasticsearch)适用于大规模数据的全文搜索和分析,具有高可扩展性和高性能。它可以处理大量的实时数据,并支持复杂的查询和聚合操作。因此,es常用于日志分析、实时监控、搜索引擎等场景。solr则更适合于传统的文档检索场景,如电子商务网站的商品搜索、新闻网站的文章搜索等。solr提供了丰富的文档处理功能和可定制的搜索结果排名算法,同时也支持分布式部署和高可用性。3.除了上述的主要应用场景外,es和solr还可以结合使用。例如,可以使用es进行实时数据的索引和分析,然后将结果存储到solr中进行文档检索。这样可以充分发挥两者的优势,满足不同的需求。另外,es和solr都是开源软件,拥有活跃的社区支持和丰富的插件生态系统,可以根据具体需求进行扩展和定制。
END,本文到此结束,如果可以帮助到大家,还望关注本站哦!
本文链接:http://xinin56.com/ruanjian/4477.html