一.Lucene简介
Lucene的倒排索引,Solr是基于Lucene的一种实现,注意Lucene的一套使用CRUD,文档,字段,目录对象,索引写入器,索引写入器配置类,IK分词器,了解下分词器(扩展词典和停用词典),分页,得分(激励因子(可用于作弊)),高亮和排序。
二.Solr
1.solr介绍:
solr是独立的企业级搜索应用服务器,是基于jetty服务器的,对外提供类似于web-service接口的api,用户可通过http请求,向搜索引擎服务器提交一定格式的文件,生成索引,也可通过提出查找请求,获得返回结果,solr实际上是封装了lucene,提供了更强大的功能(集群分布式)
下载地址:http://www.apache.org/dyn/closer.cgi/lucene/solr/
下载后的目录结构:
contrib:使用solr功能,依赖相关的jar包
dist:存放solr自己jar包和solr.war
docs:文档目录
example:存放solr的案例
案例主要有两部分组成:
a.WEB应用程序部分:
主要负责对索引库中数据进行各种操作,并提供web'形式的管理界面,它可以通过solr内嵌的jetty服务器运行,也可部署在其他的web服务器中(如tomcat)中运行,对应位置目录在:solr-4.10.2\example\webapps\solr.war
b.索引库部分:
主要负责用来存放索引数据,好比lucene中的索引库文件,solr可以同时拥有多个索引库,对应位置在:solr-4.10.2\example\solr\collection1
2.solr的安装和运行:
a.运行solr:
方式一:可通过内置的jetty服务器来运行,在进入 solr-4.10.2\example目录下后,通过java -jar运行start.jar,通过jetty服务器访问端口8983访问服务即可,通过http方式即可访问:http://localhost:8983/solr
方式二:部署tomcat服务器的方式:
A).部署Web应用程序:将solr-4.10.2/example/webapps/solr.war解压后,复制到tomcat/webapps下
B).
3.solr的基本使用:
a.配置IK分词器
b.使用管理界面,手动添加Documents
c.使用管理界面的Query功能
4.Solr core配置
a.solr core:一个core就是一个索引的服务,里面包含大量的功能(可通过handler实现),核心配置文件是schema.xml(是索引的配置,比如field等等)和solrconfig.xml(是core的搜索服务整体配置,比如索引库的位置等等)
b.solr的目录结构:
一个solr.home可以有多个core,主要包含三个配置文件:
solr.xml:整个solr服务器下的整体配置,主要用来配置当前solr下有多少个core
solrconfig.xml:每个core下的配置,例如配置索引库的位置,jar,lucene版本等等
schema.xml:每个core下的具体索引的配置,例如配置的field分词器等等。
c.solr.xml配置multicore:
如果solr.home'下没有solr.xml文件,那么solr服务器会默认去找名称为collection1的core
如果solr.xml没有任何配置,那么solr.home下的每一个文件就是一个core,在文件夹里要提高core.properties,配置name=core的名称,如果在solr.xml中配置了多个core,这样就不需要core.properties了
d.schema.xml配置文件:
A)通过<field>节点来定义建立索引查询数据的字段
name代表数据字段名称
type代表数据字段类型
indexed代表是否被索引
stored代表是否被存储
multiValued代表是否有多个值,如果字段有多个值,要尽可能的设为true
_version和_root节点建议保留,不要删除
B)通过<fieldType>节点定义数据类型
name代表节点定义的名称
class指向org.apache.solr.analysis中定义的类型名称
solr.TextField允许用户通过分析器来定制索引和查询,分析器包括一个分词器(tokenizer)和多个过滤器(filter)
<analyzer>指定分词器
也可自定义新字段:
<field name="yin" type="text_ik" indexed="true" stored="true" multiValued="true" />
动态字段定义:只要以yin开头,都能使用这个字段
<dynamicField name="yin*" type="text_ik" indexed="true" stored="true" />
e.solrconfig.xml:
A).lib引入外部jar包
可以将solr解压目录/contrib和dist复制solr.home下,修改lib的路径,引用到jar包中即可
B).索引相关配置:
<luceneMatchVersion> solr低层使用lucene版本
<dataDir> 配置索引文件位置,默认./data
<directoryFactory>配置索引的路径工厂
<indexConfig> 进行索引相关配置
C).Request Dispatcher请求转发器的配置:
<requestHandler name="/select" class="solr.SearchHandler">
<requestHandler name="/query" class="solr.SearchHandler">
<requestHandler name="/get" class="solr.RealTimeGetHandler">
<requestHandler name="/update" class="solr.UpdateRequestHandler">
wt是通讯数据格式,indent是否缩进,df是默认搜索的字段 ,q是查询条件
一般不会去改它,具体的设置还是通过外部的参数传入
5.SolrJ的基本功能:
a.概念:
solr的客户端代码和solr服务器之间的增删改查索引操作都是通过类似webservice接口API,所以在操作时,只要遵循一定的接口规范即可。
准备:导入solrJ.jar包到项目中,运行solr服务器
b.添加.修改索引(使用相同的api)
传统方式:
- /**
- * 创建索引(传统方式)
- *
- * @throws IOException
- * @throws SolrServerException
- */
- @Test
- public void createIndex1() throws SolrServerException, IOException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- // 使用solr输入文档(SolrInputDocument) 创建文档对象
- SolrInputDocument document = new SolrInputDocument();
- // 添加字段到文档对象
- document.addField("id", "3");
- document.addField("title", "这是来自solrj客户端的第一个title");
- document.addField("content", "这是来自solrj客户端的第一个content");
- //添加文档到solr服务器对象
- solrServer.add(document);
- // 提交
- solrServer.commit();
- }
bean注解方式:
创建实体bean,对实体bean添加注解@Field,直接传递bean
- import org.apache.solr.client.solrj.beans.Field;
- /**
- * @author Administrator 文章实体Bean
- */
- public class Article {
- @Field
- private String id;
- @Field
- private String title;
- @Field
- private String content;
- public String getId() {
- return id;
- }
- public void setId(String id) {
- this.id = id;
- }
- public String getTitle() {
- return title;
- }
- public void setTitle(String title) {
- this.title = title;
- }
- public String getContent() {
- return content;
- }
- public void setContent(String content) {
- this.content = content;
- }
- }
通过bean创建索引:
- /**
- * 创建索引(Bean注解方式)
- * @throws SolrServerException
- * @throws IOException
- */
- @Test
- public void createIndex2() throws IOException, SolrServerException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- for (int i = 0; i < 30; i++) {
- //创建bean
- Article article = new Article();
- //添加值
- article.setId(""+i);
- article.setTitle("这是来自solrj客户端的第一个title"+i);
- article.setContent("这是来自solrj客户端的第一个content"+i);
- //添加实体对象到solr服务器对象中
- solrServer.addBean(article);
- //提交
- }
- solrServer.commit();
- }
c.删除索引:
根据id删除:
- /**
- * 删除索引(根据id)
- * @throws IOException
- * @throws SolrServerException
- */
- @Test
- public void deleteIndex1() throws SolrServerException, IOException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- //删除
- solrServer.deleteById("2");
- //提交
- solrServer.commit();
- }
Query表达式方式:
- /**
- * 删除索引(根据Query表达式删除)
- * @throws IOException
- * @throws SolrServerException
- */
- @Test
- public void deleteIndex2() throws SolrServerException, IOException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- // 删除
- solrServer.deleteByQuery("id:1*");
- // 提交
- solrServer.commit();
- }
d.查询索引:
传统方式:
- /**
- * 查询索引(传统方式)
- * @throws SolrServerException
- */
- @Test
- public void queryIndex1() throws SolrServerException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- // 创建solr查询对象(solrquery)并且载入要查询的内容
- SolrQuery solrQuery = new SolrQuery("title:这是");
- // 添加返回结果的列
- solrQuery.addField("id");
- solrQuery.addField("title");
- // 设置查询结果返回的行数
- solrQuery.setRows(20);
- // 设置排序方式
- solrQuery.setSort("id", ORDER.desc);
- // 开始查询,返回查询响应对象(QueryResponse)
- QueryResponse response = solrServer.query(solrQuery);
- // 通过查询响应对象(QueryResponse)获得结果
- SolrDocumentList results = response.getResults();
- // 对结果进行遍历,获得solr文档对象,并打印出结果
- for (SolrDocument solrDocument : results) {
- System.out.println(solrDocument.getFieldValue("id"));
- System.out.println(solrDocument.getFieldValue("title"));
-
- //List titles = (List) solrDocument.getFieldValue("title");
- //System.out.println(titles.get(0));
-
- System.out.println(solrDocument.getFieldValue("content"));
- }
- }
bean注解方式:
- /**
- * 查询结果(返回bean形式)
- * @throws SolrServerException
- */
- @Test
- public void queryIndex2() throws SolrServerException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- // 创建solr查询对象(solrquery)并且载入要查询的内容
- SolrQuery solrQuery = new SolrQuery("title:这是");
- // 设置返回结果的列
- solrQuery.addField("id");
- solrQuery.addField("title");
- // 设置查询结果返回的行数
- solrQuery.setRows(20);
-
- // 开始查询,返回查询响应对象(QueryResponse)
- QueryResponse response = solrServer.query(solrQuery);
- // 通过查询响应对象(QueryResponse)获得结果(Bean返回形式)
- List<Article> beans = response.getBeans(Article.class);
- // 对结果进行遍历,并打印出结果
- for (Article article : beans) {
- System.out.println(article.getId());
- System.out.println(article.getTitle());
- System.out.println(article.getContent());
- }
- }
注意:如果配置schema.xml中配置指定是field的multiValued为true,其对应的实体Bean应为List,不然会出错,或者将multiValued值改为false即可。
6. SolrJ高级功能:
多条件查询:
- //new SolrQuery("查询表达式")
- SolrQuery solrQuery = new SolrQuery("title:3 or id:5");
查询结果高亮处理:
- /**
- * 查询结果(高亮模式)
- *
- * @throws SolrServerException
- */
- @Test
- public void queryIndex5() throws SolrServerException {
- // 使用HttpSolr服务端(HttpSolrServer) 创建solr服务器端对象
- HttpSolrServer solrServer = new HttpSolrServer(
- "http://localhost:8080/solr/core1");
- // 创建solr查询对象(solrquery)并且载入要查询的内容
- // new SolrQuery("查询表达式")
- SolrQuery solrQuery = new SolrQuery("title:这是");
- // 设置要查询的列
- solrQuery.addField("id");
- solrQuery.addField("title");
- solrQuery.addField("content");
- // 设置查询结果返回的行数
- solrQuery.setRows(20);
-
- /*************************高亮设置及查询********************************/
- // 是否高亮
- solrQuery.setHighlight(true);
- // 摘要长度
- solrQuery.setHighlightFragsize(50);
- // 设置前后缀
- solrQuery.setHighlightSimplePre("<font color='red'>");
- solrQuery.setHighlightSimplePost("</font>");
- // 添加高亮的field
- solrQuery.addHighlightField("title");
- // 开始查询,返回查询响应对象(QueryResponse)
- QueryResponse response = solrServer.query(solrQuery);
- System.out.println(response.getResponse());
-
- // 处理结果集 第一个Map的键是文档的ID,第二个Map的键是高亮显示的字段名
- Map<String, Map<String, List<String>>> highlighting = response
- .getHighlighting();
- for (Map.Entry<String, Map<String, List<String>>> entry : highlighting.entrySet()) {
-
- System.out.println("key:"+entry.getKey());
- System.out.println("value:" + entry.getValue());
-
- }
- /***********************************************************/
- }
7.solr数据导入并索引:
solr导入数据库中的数据
a.建立数据库,
b.配置服务器core/conf/solrconfig.xml添加导入handler
A).将/dist目录复制到solr core所在目录
B).在solrconfig.xml中添加<lib dir="../dist/" regex="solr-dataimporthandler-\d.*\.jar" />
注意相对路径一定要正确
C).core/conf中新建配置文件db-data-config.xml并写入内容:
- <?xml version="1.0" encoding="UTF-8" ?>
- <dataConfig>
- <dataSource type="JdbcDataSource"
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/solr"
- user="root"
- password="123456"/>
- <document>
- <entity name="id" query="select id,title,content from article"></entity>
- </document>
- </dataConfig>
D)在solrconfig.xml中继续添加
- <requestHandler name="/import" class="org.apache.solr.handler.dataimport.DataImportHandler">
- <lst name="defaults">
- <str name="config">db-data-config.xml</str>
- </lst>
- </requestHandler>
E).将mysql驱动包 复制 tomcat/webapps/solr/WEB-INF/lib下
F)启动服务,直接访问http://localhost:8080/solr/core1/import?command=full-import即可
到此solr学习完成啦。。。。。。。。。。。。。。。。