您现在的位置是:首页 > 技术文章 > 详情<<文章列表阅读 搜索引擎入门——启动第一个Solr应用 Solr Java 搜索引擎 wjyuian 2019-07-24 661 2 ### 零、关于Solr 摘自维基百科: > Solr(读作“solar”)是[Apache Lucene](https://zh.wikipedia.org/wiki/Lucene)项目的开源企业搜索平台。其主要功能包括全文检索、命中标示、分面搜索、动态聚类、数据库集成,以及富文本(如Word、PDF)的处理。Solr是高度可扩展的,并提供了分布式搜索和索引复制。Solr是最流行的企业级搜索引擎,Solr 4还增加了NoSQL支持。 > Solr是用Java编写、运行在Servlet容器(如[Apache Tomcat](https://zh.wikipedia.org/wiki/Apache_Tomcat)或Jetty)的一个独立的全文搜索服务器。 Solr采用了[Lucene](https://zh.wikipedia.org/wiki/Lucene) Java搜索库为核心的全文索引和搜索,并具有类似REST的HTTP/XML和JSON的API。 Solr强大的外部配置功能使得无需进行Java编码,便可对其进行调整以适应多种类型的应用程序。Solr有一个插件架构,以支持更多的高级定制。 > 因为2010年Apache Lucene和Apache Solr项目合并,两个项目是由同一个[Apache软件基金会](https://zh.wikipedia.org/wiki/Apache%E8%BD%AF%E4%BB%B6%E5%9F%BA%E9%87%91%E4%BC%9A)开发团队制作实现的。提到技术或产品时,Lucene/Solr或Solr/Lucene是一样的。 #### Solr的历史 2004年,Solr作为CNET Networks为公司网站添加搜索功能的一个内部项目,由Yonik Seeley创建。 后来Yonik Seeley随Grant Ingersoll和Erik Hatcher创建了LucidWorks(原名Lucid Imagination),公司提供商业支持、咨询和Apache Solr搜索技术的培训。 2006年1月,CNET Networks决定捐赠其到Apache软件基金会顶级项目Lucene,公开发布其源代码。像在Apache软件基金会的任何新项目一样,其进入了一个潜伏期,以助于解决组织、法律和金融问题。 2007年1月,Solr结束孵化状态,稳步成长,累积功能,从而形成聚集了用户、参与者和提交者的强大社区。即便作为一个非常新的开源项目,Solr已被应用于一些流量很高的网站。 2008年9月,Solr 1.3发布了许多增强功能,包括分布式搜索功能和性能增强等。 2009年11月,Solr 1.4发布。此版本对索引、搜索和分面做了增强,并有许多其它改进,例如富文本(PDF、Word和HTML)的处理,基于Carrot 2的搜索结果聚簇,与数据库集成的改进。该版本还提供了许多插件。 2010年3月,Lucene和Solr项目合并。产品现在由同一组参与者共同开发。 在2011年,Solr改变了版本编号方案,以便与Lucene的匹配。为了使Solr和Lucene有相同的版本号,Solr 1.4的下一版本号为3.1。 2012年10月,Solr 4.0版本发布,包括新的SolrCloud功能。 以上Solr的历史也是摘自维基百科,目前Solr的稳定版本已经升级到了8.\*。而且官方提示:<7.7的版本都是EOL(EndOfLife)版本。 #### 关于版本的选择 如果你是没有使用过Solr的初学者,亦或是正在重新选择Solr版本,那么建议你用当前的稳定版本。 如果你已经有一段时间的使用经验,而且当前使用的版本正在服役,那么建议你在功能性满足的条件下继续正在使用的版本。 工作上,在能满足可预见需求的版本中,请选择你最擅长且有把握能hold住的版本。用于学习,可以直接选择最新的稳定版本。 我在2011年11月份首次接触Solr的时候,没记错的话,当时我使用的版本就是Solr3.6。差不多经过两年的时候,当时遇到了一个需求就是商品的库存实时同步问题。大家都知道,商品信息本身变动的频率是远低于库存变动的,但是要满足有货筛选的实时性,因此将库存同步索引到solr中。但是库存的频繁变动也引起了一些不必要的开销。因为Lucene本身是不支持Document的更新的,因此每次库存变动都要将整个文档(商品)的数据重新查询并提交。不过,凑巧的是,solr在4.7.\*就提供了`原子更新`的概念,我只需要指定主键与库存值即可,其它字段的值solr会从旧文档中复制(只能复制stored=true的字段)。 所以我升级了Solr到4.7.2版本。一直到现在,Solr的官方稳定版本已经到8了,我目前工作中使用的版本依旧是4.7.2。出现以下情况,我可能会升级到最新稳定版: + 现有版本功能无法满足,类似我从3.6升级到4.7。 + 目前4.7.2版本使用了Slave-Master模式,如果单机数据量不足以支撑,可能要升级到Solr-cloud模式。根据我经验看来,单机模式在内存够用的条件下,千万级数据量是完全没问题的。不考虑缓存且关键字查询排序很复杂的情况下,查询时间依旧在1~2s,当时的单集合索引大小在40G左右。什么样的复杂查询?看下面的例子: > (( (( (( d_text_latest_first_position_title:java^15 ) OR ( d_text_latest_first_position_title:"java"~3^7 ) OR ( d_text_latest_first_company_name:java^10 ) OR ( d_text_latest_first_company_name:"java"~4^5 ) OR ( d_text_latest_second_position_title:java^5 ) OR ( d_text_latest_second_position_title:"java"~3^2 ) OR ( d_text_latest_second_company_name:java^5 ) OR ( d_text_latest_second_company_name:"java"~4^2 ) OR ( d_m_text_other_position_titles:java^3 ) OR ( d_m_text_other_company_names:java^3 ) OR ( d_text_talent_education_school:java^15 ) OR ( d_text_talent_education_school:"java"~2^7 ) OR ( d_text_talent_education_professional:java^15 ) OR ( d_text_talent_education_professional:"java"~5^7 ) OR ( d_text_nostore_work_project_detail:"java"~5^1 )) ) AND ( (( expect_city_id:33102 )) )) )) > 关键字查询字段包括最近一段经历的职位、公司;最近第二段经历的职位、公司;其他经历的职位、公司;毕业院校、专业、全文工作项目经历、简历更新时间、期望工作地点等十多个字段,每个字段的权重都是不同的情况。 + 开始全新的技术选型,开发全新的搜索服务。 分布式搜索系统包括ES和Solr-cloud并不能很好的提升查询性能(相比于Solr单机版),分布式应对的主要是索引数据量的激增所带来的问题。但是分布式会比单机模式带来更多的集群管理问题。 --- ### 一、开始 后面整个系列的文章都是基于Solr4.7.2版本,大伙参考文章的思想、思路、方法即可。Solr4.7.2版本,启动方式包括jetty和tomcat,由于习惯问题以及频繁修改Solr源码和增加扩展的需要,我选择了tomcat启动方式,这里不做两者优劣对比。 #### 下载旧版本Solr4.7.2 Solr官方当然不会建议我们使用如此之旧的EOL版本,所以旧版本入口在官网不是很好找,这里直接给出[下载Solr4.7.2](https://archive.apache.org/dist/lucene/solr/4.7.2/)的链接。  我们只要下载solr-4.7.2.zip包就行。 压缩包解压之后的目录大致如下:  大概说一下相关目录的用途: + contexts:里面只有一个`solr-jetty-context.xml`文件,顾名思义,就是配置jetty启动时上下文中的solr参数。例如jetty的``项目路径``和``项目访问根路径``。 + etc:这里存的是和jetty相关其它配置。例如jetty的``访问端口``、连接池等等。 + example-DIH:solr的一个数据导入模块的用例,DIH就是data import handler的意思。它的插件支持从数据库、xml文件、word文本等数据源导入数据到Solr索引中。不过我一般不使用,可以了解下。真实应用场景会比较复杂,一个完整的索引数据源可能由多个数据库、多个数据服务甚至多个数据仓库接口组合而成。 + example-schemaless:是一个Solr最小单元的定义举例,也就是Core,可以理解为一个有完整意义的表。比如电商搜索中的商品索引就是一个Core。 + exampledocs:也是一些样例的数据文件,主要是配合example-DIH使用的一些数据源文件。 + lib:就是存放jetty启动时用的一些jar包。 + multicore:主要是支持Solr-cloud模式下的配置。但是4.7.2的cloud模式与当前8.\*版本的cloud配置方式完全不同了,这里就不详细说明了。 + solr:Solr正式启动之后使用的目录,包括所有`Core配置`以及相关的``索引数据``。每个Collection的结构是一致的,代表一个独立的索引。 + webapps:默认配置下,是Solr的web目录,与tomcat的webapps目录一样。 + start.jar:官方提供的jetty启动脚本。 #### jetty启动 官方提供的默认启动方式就是jetty,因此在你安装了jdk环境之后,启动是很方便的: ```bash 13:57 wjyuian@wjyuianMacBookPro /Users/wjyuian/software/example % java -jar start.jar ``` + 在``/contexts/solr-jetty-context.xml``文件中配置Solr基本信息: ```XML /webapps/solr ``` + 在`/etc/jetty.xml`配置项目访问端口: ```XML 50000 1500 false ``` 或者启动时指定端口号`java -jar start.jar -Djetty.port=8985`。 + 在`/webapps/solr/WEB-INF/web.XML`中,配置solr索引的配置和数据存储目录: ```XML solr/home java.lang.String /Users/wjyuian/software/example/solr ``` #### tomcat启动 配置`tomcat/conf`目录下的server.xml文件: ```XML ``` -------- ### 二、solr索引的配置和数据存储目录 下面详细说一下solr的索引配置和数据目录。 这个目录下存放的是一个个Core,也就是一个个独立的索引。例如在招聘行业就是,职位索引、订单索引、简历索引等等的配置。  例如上图所示项目的索引配置目录,包含了大约27个Core,其中就包括职位索引、订单所以、简历索引。 #### position 我们进入到其中某一个Core,可以看到里面有两个子目录:conf和data。 conf存放的就是结构化配置,data存放的就是实际索引数据。 #### solr.xml 在索引配置的根目录下,还有一个solr.xml文件。 ```XML ``` --- ### 三、测试访问 当我们使用jetty或者tomcat启动Solr之后,通过链接`http://localhost:8985/solr/#/`就可以访问到Solr的管理页面。  在`Core Selector`下拉列表可以选择上面`solr.xml`中配置的所有Core。当选择了一个Core,点击`Query`菜单,然后`Execute Query`可以看到:  #### Core菜单介绍 + Overview:当前Core的总览数据,包括索引更新时间、文档数量、堆内存、数据版本、索引文件Segment数、主从同步状态、索引大小、Core实例的相关路径等等。 + Analysis:Core配置的分词器测试,比如Index阶段的分词、Query阶段的分词。 + Dataimport:数据导入配置,我这里没有配置。 + Documents:主要是通过接口进行索引文档的修改,一般不建议使用。 + Files:索引配置文件。需要重点关注的是schema.xml、solrconfig.xml、solrcore.properties。 + Ping:检查Core的存活情况。 + Plugins/Stats:显示Solr使用的相关插件信息、扩展信息。比如Solr的缓存配置,用到了哪些Cache;Core使用的search数据;高亮插件;查询语句分析器、转换器;数据更新插件等等。 + Query:进行Solr查询,这是最常用的页面,主要是用于索引数据查询和数据调试。 + Replication:进行索引的主从管理。显示了上次同步时间、下次同步时间、同步的数据量、同步状态、主的地址;以及手动执行同步和关闭同步操作。 + Schema Browser:对schema.xml配置进行更为全面的查看,包括静态配置数据和实时数据。 下一章将会详细介绍`schema.xml`的内容和配置。 --- 相关文章 搜索引擎进阶——IK扩展之动态加载与同义词 SpringBoot2从零开始(一)——项目启动 应用算法学习(一)—— TopN算法 重温Java设计模式——工厂模式 重温Java设计模式——建造者模式 Linux之相关工程化应用遇到的问题 Java网络编程之Netty框架学习(一) Java网络编程之Netty学习(二)—— 简单RPC实现 Java网络编程之Netty学习(三)—— RPC的服务注册、发现、降级 搜索引擎进阶——solr自定义function 栏目导航 关于我 不止技术 工程化应用(23) 技术学习/探索(32) 自娱自乐(2) 还有生活 随便写写(1) 娱乐/放松(1) 点击排行 SpringBoot2从零开始(二)——多数据源配置 搜索引擎进阶——IK扩展之动态加载与同义词 从零开发参数同步框架(二)—— 前期准备之工具类 Nginx的nginx.conf配置部分解释 springMVC中controller参数拦截问题处理 Maven项目一键打包、上传、重启服务器 微信小程序深入踩坑总结 微信小程序的搜索高亮、自定义导航条等踩坑记录 标签云 Java(19) 搜索引擎(13) Solr(7) 参数同步(6) SpringBoot(4) ES(3) ElasticSearch(3) JVM(3) Netty(3) Spring(3) mongoDB(3) 设计模式(3) Curator(2) Docker(2) Dubbo(2) 大家推荐 魔神重返战场!厄祭战争的巴巴托斯:第四形态 搜索引擎入门——Solr查询参数详解以及如何使用Java完成对接 来聊一聊这个被淘汰的图片验证码 搜索引擎入门——聊聊schema.xml配置 搜索引擎入门——启动第一个Solr应用 君子性非异也,善假于物也——功能强大的Postman 择其善而从之——我为什么开始学习ElasticSearch 实现一个关于队列的伪需求是一种怎样的体验