solr学习笔记
#
1.概述
- 企业级搜索应用服务:本质是war包,底层是lucene,比lucene更高效,实现了可配置,可扩展。
- 安装
- 本质是一个war包,按照正常的web工程发布方式,解压到tomcat的webapps目录下。
- 将下载文件目录中的solr单独拷出来,放在一个没有中文的路径下(这是solr的home文件夹,存储索引库等)
- 1.可以打开tomcat/bin/catalina.bat文件,在文件首行添加:set “JAVA_OPTS=-Dsolr.solr.home=【solr文件夹路径】”
- 2.或者打开solr项目的web.xml进行如下配置
-
solr/home
d:\solrhome
java.lang.String
- 配置分词器:在web-INF路径下创建classes文件夹(classpath),防止IK分词器配置文件(具体内容,见lucene笔记)。
- jar包引用:将相关依赖的jar包放入web-INF下的lib文件夹中。
- 启动tomcat,即可通过浏览器访问solr库。
2.SolrCore
- 在Solr中,每一个Core代表一个索引库,里面包含索引数据及其配置信息。Solr中可以拥有多个Core,也就是同时管理多个索引库,就像在MySQL中可以有多个database。存储位置在solrhome文件夹中。
常用配置文件
conf/schema.xml:字段及字段约束信息
- Field字段的属性信息。
- name:字段名称,最好以下划线或者字母开头
- type:字段类型,指向的是本文件中的标签
- indexed:是否创建索引
- stored:是否被存储
- multiValued:是否可以有多个值,如果字段可以有多个值,设置为true
- FieldType
- name:字段类型的名称,可以自定义
- class:字段类型在Solr中的类。
- analyzer:这个子标签用来指定分词器
- 唯一主键
- uniqueKey标签
- 动态字段
- 标签:dynamicField name=”item_spec_*” type=”string” indexed=”true” stored=”true”
- Field字段的属性信息。
conf/solrconfig.xml:索引库的相关配置
- lib标签:配置插件依赖的jar包
- core.properties:Core的属性文件,记录当前core的名称等信息,也可以不写内容。
3.SolrJ
- 概述:SolrJ是Apache官方提供的一套Java开发的,访问Solr服务的API
- 依赖
-
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.10.2</version>
</dependency>
<!-- Solr底层会使用到slf4j日志系统 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.22</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
</dependencies> 添加/修改字段
document添加
public void addDateToSolr() throws SolrServerException, IOException{ //solrCore访问地址 String url = "http://localhost:8080/solr/core2"; //solrj连接对象 HttpSolrServer server = new HttpSolrServer(url); SolrInputDocument document = new SolrInputDocument(); // 新增数据,数据封装对象 SolrInputDocument 提供了addField("字段名称", "字段值")设置数据 document.addField("id", 2); document.addField("name", "solr"); document.addField("age", 27L); document.addField("title", "solr是独立的企业级搜索服务器"); List<SolrInputDocument> list = new ArrayList<SolrInputDocument>(); list.add(document); //添加数据 server.add(list); //提交数据 server.commit(); }
javaBean添加
public void addJavaBeanToSolrCore() throws IOException, SolrServerException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); //同时新增多条数据 List<User> list = new ArrayList<User>(); for(int i = 3;i<30;i++){ User user = new User(); user.setId(""+i); user.setName("程序员"+i+"号"); user.setAge(Long.valueOf(""+i)); user.setTitle("机智聪明勤奋工程师"+i); list.add(user); } //直接添加javaBean 添加单条数据 //server.addBean(user); server.addBeans(list); //提交 server.commit(); }
注意:这里的User类的成员变量需要与field匹配。需要在User类的成员变量上添加@Field注解
修改字段
- 注意: solr中并没有更新数据的方法,没有更新这个概念
- 更新是怎么回事?
- 通过唯一字段来判断 schema.xml中定义了uniqueKey就是唯一字段
- 如果新增数据的唯一键已经存在,新增时会直接全覆盖
- 如果新增数据时唯一键不存在,直接新增
- 注意: solr中并没有更新数据的方法,没有更新这个概念
删除字段
根据Id
public void deleteById() throws SolrServerException, IOException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); //根据id删除对应的数据 server.deleteById("2"); server.commit(); }
根据Id集合(方法重载)
public void deleteByIds() throws SolrServerException, IOException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); //根据id删除对应的数据 List<String> ids = new ArrayList<String>(); ids.add("1"); ids.add("3"); //根据ids删除指定的数据 server.deleteById(ids); server.commit(); }
根据查询条件
public void deleteByQuery() throws SolrServerException, IOException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); String query = "title:聪明"; //根据指定的查询条件删除 删除所有匹配的结果 server.deleteByQuery(query); server.commit(); }
查找字段
普通查询
public void searchSolrCore() throws SolrServerException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); //字段名:参数值 //SolrQuery query = new SolrQuery("title:互*"); //布尔搜索 //SolrQuery query = new SolrQuery("title:solr OR title:iphone"); //子表达式查询(布尔搜索) //SolrQuery query = new SolrQuery("(title:solr OR title:聪明) OR (title:iphone)"); //相似度搜索,最大允许编辑次数为2次,这里设置为1 //SolrQuery query = new SolrQuery("iphon~1"); //数字范围搜索 包含起始值和结束值 SolrQuery query = new SolrQuery("age:[17 TO 27]"); //{}:表示不包含 []:表示包含 //根据id字段倒叙排列 query.setSort("id", ORDER.desc); QueryResponse response = server.query(query); //解析搜索的结果集方式一:返回list集合 SolrDocumentList list = response.getResults(); for(SolrDocument sd : list){ System.out.println("id===="+sd.get("id")); System.out.println("name===="+sd.get("name")); System.out.println("title===="+sd.get("title")); System.out.println("===========next==========="); } //解析搜索结果集的方式二 :直接返回javaBean的方式 List<User> list = response.getBeans(User.class); for(User u : list){ System.out.println(u); } } )
特殊查询
分页及高亮
public void searchSolrCorePageList() throws SolrServerException{ String url = "http://localhost:8080/solr/core2"; HttpSolrServer server = new HttpSolrServer(url); //页码 Integer page = 2; //每页显示条数 Integer pageSize = 15; Integer start = (page -1 ) * pageSize; //字段名:参数值 SolrQuery query = new SolrQuery("title:聪明"); //根据id字段倒叙排列 query.setSort("id", ORDER.desc); //设置分页查询 query.setStart(start); query.setRows(pageSize); //开启高亮显示(可以省略) //query.setHighlight(true); //高亮显示的标签前缀 query.setHighlightSimplePre("<em color='red'>"); //高亮显示的标签后缀 query.setHighlightSimplePost("</em>"); //添加需要高亮显示的字段 query.addHighlightField("title"); query.addHighlightField("name"); QueryResponse response = server.query(query); //高亮显示的结果集 // 外层的Map,key:id,value:id以外的其他高亮字段,可能有多个,也是一个Map // 内层的Map,key:高亮字段的名称,value:字段的内容,集合 Map<String, Map<String, List<String>>> highlighting = response.getHighlighting(); //遍历的方式获取高亮的结果集 for(String key : highlighting.keySet()){ Map<String, List<String>> map = highlighting.get(key); for(String key2 : map.keySet()){ List<String> list = map.get(key2); for(String str : list){ System.out.println(str); } } } //解析搜索结果集的方式二 :直接返回javaBean的方式 List<User> list = response.getBeans(User.class); for(User u : list){ //对应map中取值的方法 String highlightTilte = highlighting.get(u.getId()).get("title").get(0); System.out.println(highlightTilte); u.setTitle(highlightTilte); System.out.println(u); } }