文档章节

搜索系统框架(Solr)

ddyin
 ddyin
发布于 2017/04/27 13:53
字数 2564
阅读 11
收藏 0

一.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学习完成啦。。。。。。。。。。。。。。。。

 

 

 

 

 

 

 

 

 

© 著作权归作者所有

上一篇: Apache POI
下一篇: 接口调用方式
ddyin
粉丝 2
博文 92
码字总数 79320
作品 0
私信 提问
Solr简单介绍

简介 Solr是一个高性能,采用Java5开发,Solr基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提...

邵鸿鑫
2016/06/29
0
0
Lucene、solr以及elasticsearch之间的区别和联系

全球数据库排行:DB-Engines Ranking 首先分别说明三者的概念: Lucene是一套信息检索工具包,并不包含搜索引擎系统,它包含了索引结构、读写索引工具、相关性工具、排序等功能,因此在使用L...

吴伟祥
2018/08/13
836
0
推荐9个Java的搜索引擎框架

在这个信息相当繁杂的互联网时代,我们已经学会了如何利用搜索引擎这个强大的利器来找寻目标信息,比如你会在Google上搜索情人节如何讨女朋友欢心,你也会在百度上寻找正规的整容医疗机构(尽...

孟飞阳
2016/06/19
194
0
9个基于Java的搜索引擎框架

在这个信息相当繁杂的互联网时代,我们已经学会了如何利用搜索引擎这个强大的利器来找寻目标信息,比如你会在Google上搜索情人节如何讨女朋友欢心,你也会在百度上寻找正规的整容医疗机构(尽...

zh119893
2014/09/04
488
0
9个基于Java的搜索引擎框架

9个基于Java的搜索引擎框架 [导读] Lucene是目前最受欢迎的Java全文搜索框架,准确地说,它是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎。Lucene为开发人员...

引鸩怼孑
2015/07/30
790
0

没有更多内容

加载失败,请刷新页面

加载更多

【AngularJS学习笔记】02 小杂烩及学习总结

本文转载于:专业的前端网站☞【AngularJS学习笔记】02 小杂烩及学习总结 表格示例 <div ng-app="myApp" ng-controller="customersCtrl"> <table> <tr ng-repeat="x in names | orderBy ......

前端老手
昨天
8
0
Linux 内核的五大创新

在科技行业,创新这个词几乎和革命一样到处泛滥,所以很难将那些夸张的东西与真正令人振奋的东西区分开来。Linux内核被称为创新,但它又被称为现代计算中最大的奇迹,一个微观世界中的庞然大...

阮鹏
昨天
4
0
【Medium 万赞好文】ViewModel 和 LIveData:模式 + 反模式

原文作者: Jose Alcérreca 原文地址: ViewModels and LiveData: Patterns + AntiPatterns 译者:秉心说 View 和 ViewModel 分配责任 理想情况下,ViewModel 应该对 Android 世界一无所知。...

秉心说
昨天
9
0
重学计算机组成原理(十二) - 异常和中断

1 概览 完好的程序都满足以下特征 自动运行 我们的程序和指令都是一条条顺序执行,不需要通过键盘或者网络给这个程序任何输入 正常运行 没有遇到计算溢出之类的程序错误。 不过,现实的软件世...

JavaEdge
昨天
8
0
程序设计基础(C)第06讲例程

1summing.c /* summing.c -- 根据用户键入的整数求和 */#include <stdio.h>int main(void){ long num; long sum = 0L; /* 把sum 初始化为0 */ int status; p......

树人大学数字媒体吴凡
昨天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部