文章目录
什么是Solr
说到Solr ,不得不提起Lucene,Lucene是一个全文检索引擎工具包,它只是一个jar包,不能独立运行,对外提供服务。
而Solr是一个全文检索服务器,它可以单独运行在servlet容器,可以单独对外提供搜索和索引功能。Solr比lucene在开发全文检索功能时,更快捷、更方便。
Solr是apache的顶级开源项目,它是使用java开发 ,基于lucene的全文检索服务器。
Solr的索引和搜索流程
索引流程:Solr客户端(浏览器、java程序)可以向Solr服务端发送POST请求,请求内容是包含Field等信息的一个xml文档,通过该文档,Solr实现对索引的维护。
搜索流程:Solr客户端(浏览器、java程序)可以向Solr服务端发送GET请求,Solr服务器返回一个xml/json文档。
Solr界面
Dashboard
仪表盘,显示了该Solr实例开始启动运行的时间、相关Solr版本和Lucene、系统资源、JVM等信息。
Logging
显示Solr运行出现的异常或警告
像这样,十分尴尬
Core Admin
Solr Core的管理界面。在这里可以添加SolrCore实例。
主要功能有Add Core(添加核心), Unload(卸载核心),Rename(重命名核心),Reload(重新加载核心),Optimize(优化索引库) 。
关于Add Core的配置项说明
- name:给core起的名字;
- instanceDir:与我们在配置solr到tomcat里时的solrhome里新建的core文件夹名一致;
- dataDir:确认Add Core时,会在new_core目录下生成名为data的文件夹;
- config:new_core下的conf下的config配置文件(solrconfig.xml) ;
- schema: new_core下的conf下的schema文件(schema.xml) ;
Java Properties
Solr在JVM 运行环境中的属性信息,包括类路径、文件编码、jvm内存设置等信息。
Tread Dump
显示Solr Server中当前活跃线程信息,同时也可以跟踪线程运行栈信息。
Core Selector
需要在Core Admin里添加了Solr Core后才有可选项,可以选择一个Solr Core进行详细操作,有关Core Selector里的Solr Core里的相关子面板功能,已经在下面做说明。
Solr Core的子面板功能
Analysis
通过此界面可以测试索引分词器和搜索分词器的执行情况。
dataimport
可以定义数据导入处理器,从关系数据库将数据导入到Solr索引库中,默认没有配置,需要手工配置。假如没有配置,dataimport面板没有任何的功能显示。
Document
通过对文档的操作进行创建索引、更新索引、删除索引等操作。
Query
通过/select执行搜索索引,指定查询条件方可搜索。
schema.xml配置文件详解
该配置文件在solrhome目录下的相应solrcore 的conf目录下
schema.xml主要配置SolrCore的相关信息,包括:Field和FieldType的定义等信息,在Solr中,Field和FieldType都需要先定义后使用。
其中Field配置如下:
- name:指定域的名称(自定义)
- type:指定域的类型
- indexed:是否索引
是:(将分好的词进行索引,索引的目的,就是为了搜索)
否:不索引,也就是不对该field域进行搜索。
- stored:是否存储
是:将field域中的内容存储到文档域中。存储的目的,就是为了搜索显示用的
否:不将field域中的内容存储到文档域中。不存储,则搜索中没法获取该field域的值。
-
required:是否必须
-
multiValued:是否多值,比如一个Field存储多个值信息,必须将multiValued设置为true。
关于Field中的配置项,也可参考自:lucene/solr 中Field类(域)的常用类型,以及Field属性解析
其中dynamicField(动态域)配置如下:
举个栗子,比如name为“ *_i ”,那么在使用这个字段的时候,任何以i结果的字段都被认为符合这个定义。
其中uniqueKey的配置如下:
id是在Field标签中已经定义好的域名,而且该域设置为required为true。
一个schema.xml文件中必须有且仅有一个唯一键
其中copyField(复制域)的配置如下:
copyField的应用场景: 其实说的简单一点,比如现在你要查询包涵"solr"的博客, 那么你肯定要查内容,标题是否包含Java,但是solr不能像SQL那样,where tittle like ‘%solr%’ or content like ‘%solr%’. 这个时候copyField就派上用场了, 定义一个新字段,将title和content 复制到这个新字段,索引的时候,直接从这个新字段查询,这样就达到目地了。
Source: 是Field域的名称。
Dest:是destination的缩写,目标域。
其中fieldType的配置如下:
常用的fieldType属性
其中分词器的配置项如下:
Name:指定域类型的名称
Class:指定该域类型对应的solr的类型
Analyzer:指定分析器
- Type:index、query,分别指定搜索和索引时的分析器
Tokenizer:指定分词器
Filter:指定过滤器
需要注意的是,Solr7以上才内置了中文分词器,实现语义分词,Solr7以下均不支持中文按语义分词,需要手动配置中文分词器,一般使用较多的为IKAnalyzer分词器,具体配置可戳:Apache Solr 4.9上配置IKAnalyzer中文分词插件
实现MySQL数据库数据导入到solr索引库
配置solrconfig.xml
我们可以在这配置文件中配置数据导入处理器,从而实现dataimport的功能:从关系数据库将数据导入到Solr索引库中。首先查询是否存在dataimport的requestHandler,如果不存在,因此需要手动添加。在solrconfig.xml中添加如下内容
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
创建并配置data-config.xml
我们还需要创建一个data-config.xml文件,用来存放数据库连接相关信息、SQL以及查询结果映射对应域中的相关信息。在solrconfig.xml的同级目录下,创建data-config.xml文件,添加内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost:3306/new_schema?serverTimezone=UTC&tinyInt1isBit=false"
user="root"
password="root"/>
<document>
<entity name="products" query="select pid,pname,catalog_name,price,description,picture from products ">
<field column="pid" name="id"/>
<field column="pname" name="prod_pname"/>
<field column="catalog_name" name="prod_catalog_name"/>
<field column="price" name="prod_price"/>
<field column="description" name="prod_description"/>
<field column="picture" name="prod_picture"/>
</entity>
</document>
</dataConfig>
配置Field域名
修改与solrconfig.xml同目录下的schema.xml,添加如下内容:
<field name="prod_pname" type="text_ik" indexed="true" stored="true" required="true" />
<field name="prod_catalog_name" type="string" indexed="true" stored="true" required="true" />
<field name="prod_price" type="tdouble" indexed="true" stored="true" required="true" />
<field name="prod_description" type="text_ik" indexed="true" stored="true" required="true" />
<field name="prod_picture" type="string" indexed="false" stored="true" required="true" />
导入相应jar包
配置完成之后,我们需要将solr目录下的solr-dataimporthandler-4.9.0.jar、solr-dataimporthandler-extras-4.9.0.jar和mysql连接驱动jar包mysql-connector-java-8.0.11.jar加入到E:\tomcat7\tomcat-7\webapps\solr\WEB-INF\lib中
重启Tomcat
重新启动Tomcat,再打开Solr Core下的dataimport子面板,会显示如下页面,证明我们的dataimport功能部署完成
勾选上Clean、Commit选项,点击Execute开始把products表中的数据导入到Solr中,等待一段时间,导入完成
此时Solr中存在我们products表中的数据
客户端查询语法
q:
指定域名进行关键字查询,也可查询所有文档记录,查询多个条件可以条件之间用 AND 或 OR 关联
#指定域名进行关键字查询
prod_pname:花儿
#查询所有
*:*
#多个条件查询
prod_pname:花儿 AND prod_catalog_name:幽默杂货
fq:
请求fq是一个数组(多个值),可以动态添加查询条件
sort:
表示搜索出来的文档按哪个域名进行升序或降序排序,格式为sort=+<desc|asc>[,+<desc|asc>]….
prod_price:desc
start和rows:
start - 分页显示使用,开始记录下标,从0开始
rows - 指定返回结果最多有多少条记录,配合start来实现分页
f1
指定返回哪些字段内容,用逗号或空格分隔多个(回显)
df
指定一个搜索默认Field
wt
指定文档输出格式,可选,默认是json
hl
设置高亮,hl.fl 指定高亮域的名称,一般对哪个域进行搜索就对哪个域做高亮
solrj的增删改查
Solrj就是solr服务器的java客户端
创建maven工程
要用solrj实现对solr索引库的增删改查操作,首先创建个maven工程,并在pom.xml添加以下依赖
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.9.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
solrj添加数据
@Test
public void addDoc() throws SolrServerException, IOException {
//1.创建连接对象
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.创建一个文档对象
SolrInputDocument inputDocument = new SolrInputDocument();
//向文档中添加域以及对应的值,注意:所有的域必须在schema.xml中定义过
inputDocument.addField("id", "1000");
inputDocument.addField("prod_pname", "sansung爆炸牌手机");
inputDocument.addField("prod_price", 666);
inputDocument.addField("prod_picture", "www.boom.png");
inputDocument.addField("prod_description", "喵喵喵喵喵手机");
inputDocument.addField("prod_catalog_name", "手机");
//3.将文档写入索引库中
solrServer.add(inputDocument);
//提交
solrServer.commit();
System.out.println("添加成功");
}
solrj更新数据
@Test
public void updateDoc() throws SolrServerException, IOException {
//1.创建连接对象
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.创建一个文档对象
SolrInputDocument inputDocument = new SolrInputDocument();
inputDocument.addField("id", "1");
inputDocument.addField("prod_pname", "蜘蛛侠手办");
inputDocument.addField("prod_price", 999);
inputDocument.addField("prod_picture", "www.zhizhuxia.png");
inputDocument.addField("prod_description", "能力越大,责任越大");
inputDocument.addField("prod_catalog_name", "手办");
//3.将文档写入索引库中
solrServer.add(inputDocument);
//提交
solrServer.commit();
System.out.println("更新成功");
}
solrj删除数据
@Test
public void deleteDoc() throws SolrServerException, IOException
{
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//删除文档
solrServer.deleteById("1000");
//提交
solrServer.commit();
System.out.println("删除成功");
}
solrj查询数据
@Test
public void testSimpleQ() throws Exception{
//1.创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr/collection1");
//2.创建查询语句
SolrQuery query = new SolrQuery();
//3.设置查询条件
query.set("q", "id:1");
//4.执行查询
QueryResponse queryResponse = solrServer.query(query);
//5.取文档列表public class SolrDocumentList extends ArrayList<SolrDocument>
SolrDocumentList documentList = queryResponse.getResults();
for (SolrDocument solrDocument : documentList) {
//取各个文档信息
System.out.println("商品id:"+solrDocument.get("id")+" ");
System.out.println("商品标题:"+solrDocument.get("prod_pname")+" ");
System.out.println("商品价格:"+solrDocument.get("prod_price")+" ");
}
System.out.println("查询成功");
}
这里只是对solrj的增删改查功能做了简单操作,也可以戳:使用solrJ操作solr常用方法