slor搜索引擎
Apache Solr是一个流行的开源搜索服务器,它通过使用类似REST的HTTP API,这就确保你能从几乎任何编程语言来使用solr。
Solr是一个开源搜索平台,用于构建搜索应用程序。 它建立在Lucene(全文搜索引擎)之上。 Solr是企业级的,快速的和高度可扩展的。 使用Solr构建的应用程序非常复杂,可提供高性能。
solr本身也可以看成数据库,(no sql类型),但它比数据库搜索速度更快
数据库本身不能实现分词效果,而只能使用模糊查询,但是模糊查询非常低效,查询速度比较慢,由于在实际生活中,一般搜索是用的比较多的,这样数据库压力自然就很大,所以我们就让供专业的solr来做搜索功能
Solr可以和Hadoop一起使用
创建一个solr数据库的具体方法见笔记,网上,
solr连接java
导入solrj依赖
<!-- https://mvnrepository.com/artifact/org.apache.solr/solr-solrj --> <dependency> <groupId>org.apache.solr</groupId> <artifactId>solr-solrj</artifactId> <version>6.6.4</version> </dependency>
在测试文件中的crud如下
package slor.test; import static org.junit.jupiter.api.Assertions.*; import java.io.IOException; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.apache.commons.lang3.StringUtils; import org.apache.solr.client.solrj.SolrQuery; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.impl.XMLResponseParser; import org.apache.solr.client.solrj.response.QueryResponse; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import com.slor.cyf.bean.Item; class Test1 { private static HttpSolrClient httpSolrServer; @BeforeAll static void setUpBeforeClass() throws Exception { //把#号去除 httpSolrServer=new HttpSolrClient("http://localhost:8983/solr/taotao");//该版本该方法已过时 //指明slor服务器的解析方式xml,不支持json httpSolrServer.setParser(new XMLResponseParser()); //连接的超时时间 httpSolrServer.setConnectionTimeout(500); } @AfterAll static void tearDownAfterClass() throws Exception { httpSolrServer.commit(); } @Test void testInsert() throws IOException, SolrServerException { Item item=new Item(); item.setId(1L); item.setTitle("小米手机mix9"); item.setSellPoint("为发烧而生"); item.setPrice(3999L); item.setImage("http://image.taotao.com/jd/4ef8861cf6854de9889f3db9b24dc371.jpg"); item.setNum(999); item.setCreated(new Date().getTime()); item.setUpdated(item.getCreated()); httpSolrServer.addBean(item); } @Test void testDelete() throws SolrServerException, IOException { httpSolrServer.deleteById("1L"); } @Test void testUpdate() throws IOException, SolrServerException { Item item=new Item(); item.setId(1L); item.setTitle("小米手机mix9"); item.setSellPoint("极致流畅"); item.setPrice(3999L); item.setImage("http://image.taotao.com/jd/4ef8861cf6854de9889f3db9b24dc371.jpg"); item.setNum(1000); item.setCreated(new Date().getTime()); item.setUpdated(item.getCreated()); httpSolrServer.addBean(item); } @Test void testQuery() throws SolrServerException, IOException { int page=1; int rows=3; String keywords="手机"; //构造搜索条件 SolrQuery solrQuery=new SolrQuery(); //搜索关键词 solrQuery.setQuery("title:"+keywords+" AND status:1"); //设置分页start=0就是从0开始,rows=5当前返回5条记录 solrQuery.setStart((Math.max(page, 1)-1)*rows); solrQuery.setRows(rows); //是否需要高亮 boolean isHighlighting=!StringUtils.equals("*", keywords)&&StringUtils.isNotEmpty(keywords); if(isHighlighting) {//设置高亮 solrQuery.setHighlight(true);//开启高亮组件 solrQuery.addHighlightField("title");//高亮字段 solrQuery.setHighlightSimplePre("<em>");//标记高亮关键字前缀 solrQuery.setHighlightSimplePost("</em>");//高亮关键字后缀 } //执行查询 QueryResponse queryResponse=httpSolrServer.query(solrQuery); List<Item> items=queryResponse.getBeans(Item.class); //将高亮的标题数据写回到对象中 if(isHighlighting) { Map<String, Map<String,List<String>>> map=queryResponse.getHighlighting(); for(Entry<String, Map<String,List<String>>> highlighting:map.entrySet()) { for(Item item: items) { if(!highlighting.getKey().equals(item.getId().toString())) { continue; } item.setTitle(StringUtils.join(highlighting.getValue().get("title"),"")); break; } } } for(Item item: items) { System.out.println(item); } } }
与httpclient结合使用时,要注意版本兼容问题
这里将数据库的数据存入solr中
package main; import java.io.IOException; import java.util.List; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.client.solrj.impl.XMLResponseParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.slor.cyf.bean.Item; import com.slor.cyf.service.ApiService; public class TestMain { private static ApiService apiService=new ApiService(); private static ObjectMapper mapper=new ObjectMapper(); private static HttpSolrClient HttpSolrClient; public static void main(String[] args) throws JsonProcessingException, IOException, SolrServerException { HttpSolrClient=new HttpSolrClient("http://localhost:8983/solr/taotao"); int page=1; int rows=100; do { String data=apiService.getTestOne("http://manage.taotao.com/rest/item?page="+page+"&rows="+rows); JsonNode tree = mapper.readTree(data); //ArrayNode array = (ArrayNode) tree.get("rows"); List<Item> list = mapper.readValue(tree.get("rows").toString(), mapper.getTypeFactory().constructParametricType(List.class, Item.class));//这里将json字符串转化为一个List<Item>对象 page++; rows=list.size(); HttpSolrClient.addBeans(list); }while(rows==100); //指明slor服务器的解析方式xml,不支持json HttpSolrClient.setParser(new XMLResponseParser()); //连接的超时时间 HttpSolrClient.setConnectionTimeout(500); HttpSolrClient.commit(); } }
apiservice代码
public class ApiService { public String getTestOne(String url) { // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的) CloseableHttpClient httpClient = HttpClientBuilder.create().build(); // 创建Get请求 HttpGet httpGet = new HttpGet(url);//controller层的测试地址 // 响应模型 CloseableHttpResponse response = null; try { // 由客户端执行(发送)Get请求 response = httpClient.execute(httpGet); // 从响应模型中获取响应实体 HttpEntity responseEntity = response.getEntity(); System.out.println("响应状态为:" + response.getStatusLine()); if (responseEntity != null) { System.out.println("响应内容长度为:" + responseEntity.getContentLength()); return EntityUtils.toString(responseEntity); } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 释放资源 if (httpClient != null) { httpClient.close(); } if (response != null) { response.close(); } } catch (IOException e) { e.printStackTrace(); } }return null; } }