一.Solr的简介

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务。Solr可以独立运行在Jetty、Tomcat等这些Servlet容器中。都是Web服务器,Servlet容器,报文 ,JSON 格式字符串, XML格式字符串。Solr是一个可以独立运行的搜索服务器,使用solr进行全文检索服务的话,只需要通过http请求访问该服务器即可。

使用Solr 进行创建索引和搜索索引的实现方法很简单,如下:

  • 创建索引:客户端(可以是浏览器可以是Java程序)用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr服务器根据xml文档添加、删除、更新索引 。
  • 搜索索引:客户端(可以是浏览器可以是Java程序)用 GET方法向 Solr 服务器发送请求,然后对 Solr服务器返回Xml、json等格式的查询结果进行解析。Solr不提供构建页面UI的功能。Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。

二.Solr和Lucene的区别

Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索应用。Lucene仅提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索应用。

Solr的目标是打造一款企业级的搜索引擎系统,它是基于Lucene一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

三.Solr的单机与集群概念

1.Solr的单机版

概念:HttpSolrServer

2.Solr的集群版

概念:SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud。当一个系统的索引数据量少的时候是不需要使用SolrCloud的,当索引量很大,搜索请求并发很高,这时需要使用SolrCloud来满足这些需求

结构:SolrCloud为了降低单机的处理压力,需要由多台服务器共同来完成索引和搜索任务。实现的思路是将索引数据进行Shard(分片)拆分,每个分片由多台的服务器共同完成,当一个索引或搜索请求过来时会分别从不同的Shard的服务器中操作索引。SolrCloud需要Solr基于Zookeeper部署,Zookeeper是一个集群管理软件,由于SolrCloud需要由多台服务器组成,由zookeeper来进行协调管理。

一个collection可以把数据(索引文件)拆分成多份,放进几个不同的shard中,一个shard的数据可以有多个备份(replica)。一个shard的多个replica中会有一个leader,由选举程序推选出来。一个replica相当于一个core。
 
这个功能的主要特性是:
  • 整个集群的配置信息可以集中配置
  • 对于搜索自动负载均衡、出现故障时可以自动切换
  • 集成了ZooKeeper,负责集群的协调和配置

 
如上图,一个collection(collection1)被拆分到两个不同的shard中,而每个shard都有两个服务器(node)提供负载均衡和遇错切换的服务。这个分布式的结构是由ZooKeeper负责管理的。那些node中,实心圆圈的就是leader。
 
相关概念:
  • HA:High Availability
  • Node:一个服务器、或虚拟服务器节点,每个node对应一个port向外提供服务。对应于一个JVM。
  • Collection:一个SolrCloud实例,负责对一批数据建立一个索引,并提供基于这个索引的搜索服务
  • Shard:一个SolrCloud中的索引可以被拆分存放到多个shard中
  • Replica:一个shard中的数据,可以有多个副本,就是Replica,其中有一个被推选出来的leader
  • Core:负责处理一个Replica,跟一个node对应
  • Cluster:由ZooKeeper管理的多个Node的集合,对solr的请求可以发送给一个cluster
Shard的数量决定了索引是如果被拆分的,所以,当一个cluster初始化完成之后,shard的数量是不能改的。
创建一个新的core并加入到一个Collection和shard中:
 
Shard的迁移:
如果原来只有一个机器、或只有少量机器,可以先规划好shard的数量并启动,然后等有新的机器之后,在新的机器中为某个shard启动一个新的replica,然后把原来的shard移除,这样ZooKeeper就会把新的replica提升为这个shard的leader了。
 
Leader和Replica:
如果Solr启动的时候,参数numShards=2,那么前两个启动的node就是leader,分别服务于这两个shard,第三个和之后启动的node就是replica,他们会依次按照那两个leader加入cluster的顺序分配给那两个leader(使用round-robin的方式)。也可以在启动node的时候使用shardId参数直接把这个node分配给某个shard。当solr重启的时候,所有的node还是归属到重启之前所归属的shard,同个shard中先启动的node就是leader(first come first served)。
当一个leader无法工作的时候,这个shard中的某一个replica会被自动推选为leader。在Solr Admin UI界面中,Cloud菜单里面可以看到哪个是Leader(实心圆圈者)。
 
新的文档可以被送往任何一个node,SolrCloud会自动把它们分配到合适的shard中:
  • 如果文档被送到一个replica中,那么这个replica会把这些文档发送给这个shard的leader
  • 当一个leader接收到文档的时候,SolrCloud会决定这些文档应该分配到哪个shard,然后把它们发生给这个shard的leader、建立索引、并把索引发送给这个shard中所有的replica
添加shard:
如果需要加多一个shard,可以使用Collections API,创建两个新的shard,再把现有shard中的索引分配到这两个新Shard中。旧的shard需要手动删掉。
package com.xyg.solrj;

import java.util.List;
import java.util.Map;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test; /**
* <p>Title:SolrjDemo</p>
* @Description:solrj的入门程序
* @Param:
* @Return:
* @Author:Administrator
* @Date:2017年11月3日上午12:32:42
*/
public class SolrjDemo {
//添加 修改
@Test
public void testCreateAndUpdateIndex() throws Exception {
// 1. 创建HttpSolrServer对象
// 设置solr服务接口,浏览器客户端地址http://127.0.0.1:8080/solr/#/
String baseURL = "http://127.0.0.1:8080/solr";
//String baseURL = "http://localhost:8080/solr/collection2";
SolrServer solrServer = new HttpSolrServer(baseURL);
// 2. 创建SolrInputDocument对象
SolrInputDocument document = new SolrInputDocument();
document.addField("id", "");
document.addField("name", "Hello world!");
// 3. 把SolrInputDocument对象添加到索引库中
solrServer.add(document); //httpSolrServer.add(document,1000);
// 4. 提交
solrServer.commit();
}
//删除
@Test
public void testDeleteIndex() throws Exception {
String baseURL = "http://127.0.0.1:8080/solr";
SolrServer solrServer = new HttpSolrServer(baseURL);
// 根据id删除索引数据
//solrServer.deleteById("100");
// 根据条件删除(如果是*:*就表示全部删除,慎用)
//solrServer.deleteByQuery("name:Hello");
solrServer.deleteByQuery("*:*"); //删除所有
solrServer.commit(); // 提交
}
//查询
@Test
public void testSearchIndex1() throws Exception {
String baseURL = "http://127.0.0.1:8080/solr";
SolrServer solrServer = new HttpSolrServer(baseURL);
// 创建搜索对象
SolrQuery query = new SolrQuery();
// 设置搜索条件
query.setQuery("*:*");
// 发起搜索请求
QueryResponse response = solrServer.query(query);
// 处理搜索结果
SolrDocumentList docs = response.getResults();
System.out.println("搜索到的结果总数:" + docs.getNumFound());
// 遍历搜索结果
for (SolrDocument doc : docs) {
System.out.println("----------------------------------------------------");
System.out.println("id:" + doc.get("id"));
System.out.println("name:" + doc.get("name"));
}
}
//复杂查询索引
@Test
public void queryIndex2() throws Exception {
//创建连接
SolrServer solrServer = new HttpSolrServer("http://localhost:8080/solr");
//创建一个query对象
SolrQuery solrQuery = new SolrQuery();
//设置关键词查询条件
solrQuery.setQuery("钻石"); //solrQuery.set("q","钻石");
//过滤条件
solrQuery.setFilterQueries("product_catalog_name:幽默杂货");
//排序条件
solrQuery.setSort("product_price", ORDER.asc);
//分页处理
solrQuery.setStart();
solrQuery.setRows();
//结果中域的列表 solrQuery.setFields("id","product_name","product_price","product_catalog_name","product_picture");
//设置默认搜索域
solrQuery.set("df", "product_keywords");
//高亮显示
solrQuery.setHighlight(true);
//高亮显示的域
solrQuery.addHighlightField("product_name");
//高亮显示的前缀
solrQuery.setHighlightSimplePre("<font color='red'>");
//高亮显示的后缀
solrQuery.setHighlightSimplePost("</font>");
//执行查询
QueryResponse queryResponse = solrServer.query(solrQuery);
//取查询结果
SolrDocumentList solrDocumentList = queryResponse.getResults();
//共查询到商品数量
System.out.println("共查询到商品数量:" + solrDocumentList.getNumFound());
//遍历查询的结果
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id"));
//取高亮显示
String productName = "";
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
List<String> list = highlighting.get(solrDocument.get("id")).get("product_name");
//判断是否有高亮内容
if (null != list) {
productName = list.get();
} else {
productName = (String) solrDocument.get("product_name");
}
System.out.println(productName);
System.out.println(solrDocument.get("product_price"));
System.out.println(solrDocument.get("product_catalog_name"));
System.out.println(solrDocument.get("product_picture"));
}
}
}

Solr的入门知识的更多相关文章

  1. Solr搜索引擎入门知识汇总

    1.技术选型,为什么用solr而不用lucene,或者其他检索工具 lucene:需要开发者自己维护索引文件,在多机环境中备份同步索引文件很是麻烦 Lucene本质上是搜索库,不是独立的应用程序.而S ...

  2. Solr安装入门、查询详解

    Solr安装入门:http://www.importnew.com/12607.html 查询详解:http://www.360doc.com/content/14/0306/18/203871_35 ...

  3. [置顶] Mysql存储过程入门知识

    Mysql存储过程入门知识 #1,查看数据库所有的存储过程名 #--这个语句被用来移除一个存储程序.不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程 #SELECT NAME FROM ...

  4. 移动H5开发入门知识,CSS的单位汇总与用法

    说到css的单位,大家应该首先想到的是px,也就是像素,我们在网页布局中一般都是用px,但是近年来自适应网页布局越来越多,em和百分比也经常用到了.然后随着手机的流行,web app和hybrid a ...

  5. H5移动端开发入门知识以及CSS的单位汇总与用法

    说到css的单位,大家应该首先想到的是px,也就是像素,我们在网页布局中一般都是用px,但是近年来自适应网页布局越来越多,em和百分比也经常用到了.然后随着手机的流行,web app和hybrid a ...

  6. Java web 入门知识 及HTTP协议详解

     Java  web  入门知识 及HTTP协议详解 WEB入门 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资 ...

  7. Java基础入门知识

    Java编程入门知识   知识概要: (1)Java入门基本常识 (2)Java的特性跨平台性 (3)Java的编程环境的搭建 (4)Java的运行机制 (5)第一个Java小程序入门 (1)Java ...

  8. zabbix入门知识

    zabbix入门知识 zabbix中文手册 https://www.zabbix.com/documentation/3.4/manual/ 1.zabbix介绍 Zabbix 是一个企业级的分布式开 ...

  9. React的入门知识与概念【1】

    回顾在以往的项目开发中,从最初的使用的原生html+js+css+jquery开发,到后来随着项目功能的增加,也渐渐学习了Vue.js框架的开发,以及Vue.js的全家桶Axios,Vue-route ...

随机推荐

  1. Docker registry私有仓库(七)

    Docker registry私有仓库搭建基本几步流程(采用nginx+认证的方式) 1. 申请免费的ssl证书 https://buy.wosiqn.com/free 2. 设置nginx ssl证 ...

  2. P2657 [SCOI2009]windy数

    P2657 [SCOI2009]windy数 题目描述 windy定义了一种windy数.不含前导零且相邻两个数字之差至少为2的正整数被称为windy数. windy想知道, 在A和B之间,包括A和B ...

  3. CIDR 无类别域间路由

    参考百度百科 1.全称 CIDR的全称是Classless Inter-Domain Routing 2.作用 CIDR将路由集中起来,使一个IP地址代表主要骨干提供商服务的几千个IP地址,从而减轻I ...

  4. 数据分析与展示---Matplotlib基本绘图函数

    一:基本绘图函数(这里介绍16个,还有许多其他的) 二:pyplot饼图plt.pie的绘制 三:pyplot直方图plt.hist的绘制 (一)修改第二个参数bins:代表直方图的个数,均分为多段, ...

  5. Spring boot 集成 mybaits plus(代码生成器)

    源码地址:https://github.com/YANGKANG01/Spring-Boot-Demo 代码生成操作 在pom.xml文件中引入以下包: <!-- mybatisplus与spr ...

  6. 前端案例分享(一):CSS+JS实现流星雨动画

    目录 引言 1.效果图 2.源码 3.案例解析 4.小问题 5.结语 引言        平常会做一些有意思的小案例练手,通常都会发到codepen上,但是codepen不能写分析.        所 ...

  7. Dubbo学习笔记1:使用Zookeeper搭建服务治理中心

    Zookeeper是Apache Hadoop的子项目,是一个树形的目录服务,支持变更推送,适合作为Dubbo服务的注册中心,工业强度较高,推荐生成环境使用. , 下面结合上图介绍Zookeeper在 ...

  8. Machine Learning Trick of the Day (2): Gaussian Integral Trick

    Machine Learning Trick of the Day (2): Gaussian Integral Trick Today's trick, the Gaussian integral ...

  9. 【leetcode 简单】 第五十九题 同构字符串

    给定两个字符串 s 和 t,判断它们是否是同构的. 如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的. 所有出现的字符都必须用另一个字符替换,同时保留字符的顺序.两个字符不能映射到同一 ...

  10. js操作控制iframe页面的dom元素

    1.代码1  index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...