solr学习,
solr是一个基于lucene的搜索引擎,可以实现全文搜索。它对外提供类似于Web-service的API接口,可以通过http请求
进行操作。
solr可以很方便的实现一个站内搜索功能(http://zookeeper.apache.org/中的搜索)
solr的特点
通过HTTP协议处理搜索和查询请求。
增加了缓存,让响应速度更快。
提供了一个基于web的管理界面
查询结果分类(facet)
支持分布式,支持大规模的部署(solrcloud)(Solr4.0版本开始)
solr启动
tar -zxvf solr-4.10.4.tgz
cd solr-4.10.4\example
java -jar start.jar
启动后可以通过web页面访问solr
http://hostname:8983/solr
分析solr查询界面功能
Solr的检索运算符
1. “:” 指定字段查指定值,如返回所有值*:*
2. “?” 表示单个任意字符的通配
3. “*” 表示多个任意字符的通配
4. “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词;roam~0.8,检索返回相似度在0.8以上的记录。
5. 邻近检索,如检索相隔10个单词的”apache”和”jakarta”,”jakarta apache”~10
6. “^” 控制相关度检索,如检索jakarta apache,同时希望去让”jakarta”的相关度更加好,那么在其后加上”^”符号和增量值,即jakarta^4 apache
7. 布尔操作符AND、||
8. 布尔操作符OR、&&
9. 布尔操作符NOT、!、- (排除操作符不能单独与项使用构成查询)
10.“+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在
11. ( ) 用于构成子查询
12. [] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710]
13. {} 不包含范围检索,如检索某时间段记录,不包含头尾
date:{200707 TO 200710}
Solr 查询参数之 fq (Filter Query):
fq 值是一个查询,用于过滤查询结果,在负责查询时,可以很好的提高查询效率,fq 查询的内容会被缓存着,下次使
用相同的过滤查询时,可以从缓存中命中。
使用 fq 参数时需要注意以下几点
在一个查询中,fq 参数可以设置多次。结果中将返回这些过滤条件的交集
过滤查询的结果将被分别缓存
使用filter query可以充分利用filter query cache,提高检索性能。
hl高亮
hl.fl:用空格或逗号隔开的字段列表
注意:要启用某个字段的高亮功能,需要保证这个字段在schema中是store。
hl.simple.pre:前缀 可以设置标签例如 <font>
hl.simple.post:后缀 可以设置标签例如 </font>
高亮需要注意的问题
对于multiValued=true的字段不要设计高亮显示
因为solr对于这个字段里面的多个值只会返回匹配高亮的那个值
高亮时记得你的schema.xml文件中要配主键(<uniqueKey>id</uniqueKey>)
因为solr对高亮的设计是,高亮部分跟结果集部分是分开返回的,如果没有配主键,那么高亮部分就无法和结果集匹
配,不能够确定高亮的是哪条记录的。
Facet参数
(类似于sql中的group by)
facet.query
price:[* TO 20]
price:[21 TO *]
在Raw Query Parameters中可以查询多个
facet=on&facet.query=price:[* TO 20]&facet.query=price:[21 TO *]
facet.field
根据某个字段进行分组统计
facet.prefix
表示Facet字段值的前缀.比如”facet.field=cpu&facet.prefix=Intel”,那么对cpu字段进行Facet查询,返回的cpu都是
以”Intel”开头的,”AMD”开头的cpu型号将不会被统计在内
几个重要的分词器
使用IKAnalyzer2012分词
下载地址:
https://code.google.com/p/ik-analyzer/downloads/list
第一种添加IK分词工具方法
在solrconfig.xml中添加<lib dir="${solr.install.dir:../../..}/contrib/analysis-extras/lib" regex=".*\.jar" />
把IKAnalyzer2012FF_u1.jar复制到solr-4.10.4\contrib\analysis-extras\lib目录下 ,IKAnalyzer.cfg.xml,stopword.dic
这几个文件放置到solr-web类路径下(classes) 重启solr
IKAnalyzer.cfg.xml配置文件内容:
<properties>
<comment>扩展使用指定的词库</comment>
<entry key="ext_dict">my.dic</entry>
<!--可以在这里配置自己停用词-->
<entry key="ext_stopwords">stopword.dic</entry>
</properties>
修改schema.xml文件
第二种添加IK分词工具方法
把IKAnalyzer2012FF_u1.jar包导入solr-web应用下的lib目录下
把IKAnalyzer.cfg.xml和stopword.dic文件放置到solr-web类路径下(classes)
添加自定义词库
搜狗词库(sougou.dic),修改IKAnalyzer.cfg.xml
使用solrJ访问solr
SolrJ是封装了httpClient方法,来操作solr的API的
添加solrJ依赖
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.10.4</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
package cn.crxy.solr;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
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;
public class TestSolr {
public static void main(String[] args) throws Exception {
String url = "http://localhost:8983/solr/collection1";
HttpSolrServer httpSolrServer = new HttpSolrServer(url);
add(httpSolrServer);
query(httpSolrServer);
queryToBean(httpSolrServer);
}
private static void queryToBean(HttpSolrServer httpSolrServer)
throws SolrServerException {
SolrQuery params = new SolrQuery();
params.set("q", "*:*");
QueryResponse response = httpSolrServer.query(params);
List<SolrVo> beans = response.getBeans(SolrVo.class);
for (SolrVo solrVo : beans) {
System.out.println(solrVo.getId() + ":" + solrVo.getName());
}
}
private static void add(HttpSolrServer httpSolrServer)
throws SolrServerException, IOException {
SolrInputDocument solrInputDocument = new SolrInputDocument();
solrInputDocument.addField("id", "123");
solrInputDocument.addField("name", "zhangsan1");
httpSolrServer.add(solrInputDocument);
httpSolrServer.commit();
}
private static void query(HttpSolrServer httpSolrServer)
throws SolrServerException {
//设置查询参数
SolrQuery params = new SolrQuery();
params.set("q", "*:*");
QueryResponse response = httpSolrServer.query(params);
SolrDocumentList results = response.getResults();
System.out.println("总数:" + results.getNumFound());
for (SolrDocument solrDocument : results) {
Collection<String> fieldNames = solrDocument.getFieldNames();
for (String fieldName : fieldNames) {
System.out.println(fieldName + ":" + solrDocument.get(fieldName));
}
System.out.println("--------------------------------");
}
}
}
package cn.crxy.solr;
import org.apache.solr.client.solrj.beans.Field;
public class SolrVo {
@Field
private String id;
@Field
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
solr主从结构
在多个节点上分别启动solr时,可以指定主从节点。从节点按设置的周期定时同步数据,保证所有节点的数据状态一
致性。除了按设置的周期同步,在主节点启动和数据提交时也会进行同步。
修改solrconfig.xml文件1240行(vi 下执行:1240 可以调到指定行)
<requestHandler name="/replication" class="solr.ReplicationHandler" >
<!--
<lst name="master">
<str name="replicateAfter">commit</str>
<str name="replicateAfter">startup</str>
<str name="confFiles">schema.xml,stopwords.txt</str>
</lst>
-->
<!--
<lst name="slave">
<str name="masterUrl">http://your-master-hostname:8983/solr</str>
<str name="pollInterval">00:00:60</str>
</lst>
-->
</requestHandler>
动态设置主从节点
启动的时候指定 java -Dmaster=disabled -jar start.jar 或java -Dslave=disabled -jar start.jar
在配置文件中需要这样修改
<lst name="${master:master} ">
<lst name="${slave:slave}">
Replication 的实现
Master 是感知不到 Slave 的存在的, Slave 会周期性的轮询 Master 来查看当前的索引版本。如果 Slave 发现有新的
版本,那么 Slave 启动复制进程。步骤如下:
1. Slave 发出一个 filelist 命令来收集文件列表。这个命令将返回一系列元数据( size , lastmodified , alias 等
等)
2. Slave 查看它本地是否有这些文件,然后它会开始下载缺失的文件 ( 使用命令 filecontent) 。如果连接失败,则下
载终止。它将重试 5 次,如果仍然失败则放弃。
3. 文件被下载到了一个临时目录。因此,下载中途出错不会影响到 slave 。
4. 一个 commit 命令被 ReplicationHandler 执行,然后新的索引被加载进来
SolrCloud
将索引库中的索引文件进行分片,分布到集群中,每个分片以上述主从机制形成多个副本,当每个分片的master节点
宕机后,自动将从节点切换成主节点形成高可用。
启动solrCloud $ bin/solr -e cloud