单纯的对已有数据进行搜索时,Solr更快。
建立索引时,搜索效率下降,实时索引搜索效率不高。Solr的架构不适合实时搜索的应用
1.solr目录结构
- bin:该目录下存放了Solr的工具命令。
- contrib:该目录下存放了Solr所依赖的第三方JAR包
- dist:该目录下存放了Solr本身的JAR包。
其中solrj-lib的JAR包是Java客户端需要的JAR包。
SolrJ、SolrPHP、SolrC、SolrXxx……
- docs:该目录下存放了Solr的文档。
- example:该目录下存放了Solr的各种示例。
其中exampledocs和films目录下存放了Solr的示例文档。
- server:Solr自带的Web应用。
server\lib的JAR包其实就是Jetty服务器+Servlet规范包。
保证Solr可以在不需要部署到任何Web服务器时即可运行(其实是用Jetty作为服务器)
- solr-webapp:该目录下存放了Solr的Web应用——该应用可拿来部署
2. 配置在tomcat
https://blog.csdn.net/qq_40580023/article/details/83866303
初始化solr_home的数据,在solr_home文件下建一个core1(名字随意取),复制solr_home/configsets/_default/下的conf文件夹,到新建的core1下,在core1下创建文件夹data(空文件加即可)和core.properties文件(内容只配置name=core1即可,这里的name的值也就是再页面要显示的solr_home名称)
3. 后台界面介绍
启动tomcat访问solr'后台
http://192.168.233.133:8983/solr/index.html#/new_core/query
https://blog.csdn.net/qq1031893936/article/details/80229757
官网停止了ik分词器的更新,这个版本可以兼容7.x的solr
4. 配置中文分词器
将IK分词器的jar包放在tomcat下solr应用下的lib文件夹下,比如:
solr7/solr-tomcat/webapps/solr/WEB-INF/lib,然后找到managed-schema
vim solr7/solr_home/new_core/managed-schema
# 末尾添加
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
# 配置查询类型
# Indexed=true 就是可以查询
# Stored=true 就是内容存储
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="plong" indexed="true" stored="true"/>
启动solr测试,可以看到设置的查询类型
5. 获取数据
这里以数据库5.x版本为例,8.x需更改配置,linux连接windows需要windows的ip地址,并使用户支持远程连接,详情百度全都有。
1、 引入jar依赖:
-1 在apache-tomcat-8.5.23/webapps/solr/WEB-INF/lib/引入mysql的驱 动(mysql-connector-java-5.1.32.jar);
-2 复制solr-7.3.0/dist/的solr-dataimporthandler-7.3.0.jar和solr-dataimporthandler-extras-7.3.0.jar,
到apache-tomcat-8.5.23/webapps/solr/WEB-INF/lib/的下面
2、 复制solr-7.3.0/example/example-DIH/solr/db/conf/下的db-data-config.xml到solr_home/core1/conf/下,
此处改名为data-config.xml(可以不改名)。修改内容的结果为:
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/shopping"
user="root"
password="123"/>
<document>
<entity name="ec_article"
query="select id,title,price,locality,create_date from ec_article">
</entity>
</document>
</dataConfig>
3、修改solrconfig文件,添加导入信息。该信息必须放在requestHandler标签的同级位置。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
4、自定义solr的字段,在managed-schema文件中添加filed字段。(位置放在 text 字段后面即可)
<field name="title" type="text_ik" indexed="true" stored="true" multiValued="false"/>
<field name="content" type="string" indexed="false" stored="true" multiValued="false"/>
<field name="create_user_name" type="string" indexed="true" stored="true" multiValued="false"/>
<field name="create_time" type="pdate" indexed="true" stored="true" multiValued="false"/>
5、添加IK分词器,引入IK分词器的依赖到apache-tomcat-8.5.23/webapps/solr/WEB-INF/lib/下,配置IK分词器(注意:放在fieldType同级附近)。
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
启动solr,以下为运行成功后界面:
6. 数据操作
来到Documents页面
# 新增数据
{id:0,title:"高露洁"}
# 修改数据
{id:0,title:"牙牙乐"}
# 删除,格式选为xml
<delete>
<query>id:0</query>
</delete>
<commit/>
Query查询页面
默认查询locality为深圳的id和title
过滤价格3000以下商品并升序排序
查询locality like `美国`并将locality为`美国`的标红
7.solrj实现
利用java代码实现增删查改
commons-io-2.5.jar
commons-math3-3.6.1.jar
httpclient-4.5.3.jar
httpcore-4.4.6.jar
httpmime-4.5.3.jar
jcl-over-slf4j-1.7.24.jar
noggit-0.8.jar
slf4j-api-1.7.24.jar
solr-solrj-7.5.0.jar
stax2-api-3.1.4.jar
woodstox-core-asl-4.4.1.jar
zookeeper-3.4.11.jar
public class Solrj_index_crud {
public static void main(String[] args) throws SolrServerException, IOException {
// 添加或更新索引 根据id值来进行添加或更新
// addOrUpdate();
// 通过solr进行索引的删除
// delete();
// 通过solrj进行全文检索
search();
}
private static void search() throws SolrServerException, IOException {
HttpSolrClient client = new HttpSolrClient.Builder("http://192.168.233.133:8983/solr/test_core")
.withConnectionTimeout(10000).build();
// 创建solrjquery实例,通过这个对象可以设置查询的关键字 设置fl dl 高亮信息 分页等等
SolrQuery solrQuery = new SolrQuery();
// 设置查询关键字
solrQuery.setQuery("中国");
// 设置查询属性
solrQuery.set("df", "locality");
// 过滤条件,设置要显示的属性
solrQuery.set("fl", "id,title,price,locality,create_date");
// 设置分页
// solrQuery.setStart(0);
// solrQuery.setRows(2);
// 设置过滤条件
solrQuery.set("fq", "price:[3000 TO *]");
// 设置高亮
solrQuery.setHighlight(true);
// 制定高亮的字段
solrQuery.addHighlightField("locality");
// 设置高亮相关格式
solrQuery.setHighlightSimplePre("<font color='red'>");
solrQuery.setHighlightSimplePost("</font>");
// 将solrQuery传入client进行查询
QueryResponse queryResponse = client.query(solrQuery);
// 获取普通结果集
SolrDocumentList solrDocumentList = queryResponse.getResults();
// 获取高亮后的结果集
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
/*
* key:存放记录的id value:文档信息 key:字段(id,title,price) value:字段对应的值
*/
// 获取得分最高的记录分数
Float float1 = solrDocumentList.getMaxScore();
System.out.println("最高得分" + float1);
// 获取总记录数
long num = solrDocumentList.getNumFound();
System.out.println("num" + num);
// 通过forEach遍历获取每一条记录数
for (SolrDocument doc : solrDocumentList) {
// 高亮前的效果
String id = (String) doc.get("id");
String title = (String) doc.get("title");
float PRICE = (float) doc.get("price");
Date CREATE_DATE = (Date) doc.get("create_date");
String LOCALITY = (String) doc.get("locality");
System.out.println("id:" + id + "title" + title + "price" + PRICE + "create_date" + CREATE_DATE + "locality"
+ LOCALITY);
// 获取高亮后的数据
Map<String, List<String>> docMaps = highlighting.get(id);
String LOCALITY1 = docMaps.get("locality").get(0);
System.out.println("locality" + LOCALITY1);
}
}
private static void delete() throws SolrServerException, IOException {
// 创建solrj客户端对象,通过该对象与solr应用交互
HttpSolrClient client = new HttpSolrClient.Builder("http://192.168.233.133:8983/solr/test_core")
.withConnectionTimeout(10000).build();
client.deleteById("0");
client.commit();
client.close();
}
private static void addOrUpdate() throws SolrServerException, IOException {
// 创建solrj客户端对象,通过该对象与solr应用交互
HttpSolrClient client = new HttpSolrClient.Builder("http://192.168.233.133:8983/solr/test_core")
.withConnectionTimeout(10000).build();
// 创建文档实例,一个文档实例代表一条记录
SolrInputDocument document = new SolrInputDocument();
// 通过SolrInputDocument指定列以及值的信息
// 通过UUID生成id值(id已存在,则更新)
// String id = UUID.randomUUID().toString();
document.addField("id", 0);
document.addField("title", "立白");
document.addField("locality", "中国");
document.addField("price", 6);
document.addField("create_date", new Date());
client.add(document);
client.commit();
client.close();
}
}
8. 在web中的应用
addArticle.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
<h2>添加商品</h2>
<form action="${pageContext.request.contextPath}/AddArticle" method="post">
<table>
<tr><td>商品名</td><td><input type="text" name="title"/></td></tr>
<tr><td>商品价格</td><td><input type="number" name="price"/></td></tr>
<tr><td>商品产地</td><td><input type="text" name="locality"/></td></tr>
<tr><td><input type="submit" value="添加"/></td><td><input type="button" value="跳转到列表页面" onclick="window.location='${pageContext.request.contextPath}/listArticle.jsp'"/>
</td></tr>
</table>
</form>
</center>
</body>
</html>
listArticle.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
<h2>商品列表</h2>
<form action="${pageContext.request.contextPath}/ListArticleController" method="post">
<input type="text" name="keyword" value="${keyword}"/>
<input type="submit" value="检索"/><input type="button" onclick="window.location='addArticle.jsp'" value="跳转至添加商品页面"/>
</form>
<c:choose>
<c:when test="${not empty articles}">
<table>
<tr><td>商品名</td><td>商品价格</td><td>商品产地</td><td>商品日期</td></tr>
<c:forEach items="${articles}" var="article">
<tr><td>${article.title}</td><td>${article.price}</td><td>${article.locality}</td><td>${article.create_date}</td></tr>
</c:forEach>
</table>
</c:when>
<c:otherwise>
未查询到相关信息!
</c:otherwise>
</c:choose>
</center>
</body>
</html>
bean
public class Article {
private String id;
private String title;
private float price;
private String locality;
private Date create_date;
}
AddArticleController.java
protected void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{
request.setCharacterEncoding("utf-8");
//获取商品的信息
String locality=request.getParameter("locality");
String title=request.getParameter("title");
float price=Float.valueOf(request.getParameter("price"));
Date create_date=new Date();
Article article=new Article();
article.setLocality(locality);
article.setPrice(price);
article.setTitle(title);
article.setCreate_date(create_date);
//创建Service层实例
ArticleService service=new ArticleService();
try {
service.addArticle(article);
} catch (SolrServerException e) {
e.printStackTrace();
}
request.getRequestDispatcher("/addArticle.jsp").forward(request, response);
}
ListArticleController.java
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置编码防止中文乱码
request.setCharacterEncoding("utf-8");
// 获取查询关键字
String keyword = request.getParameter("keyword");
request.setAttribute("keyword", keyword);
// 创建服务层实例
ArticleService service = new ArticleService();
// 根据用户输入的关键字进行检索
List<Article> articles = null;
try {
articles = service.getAllArticleBykeyWork(keyword);
} catch (SolrServerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 将查询到的数据进行存储
request.setAttribute("articles", articles);
// 跳转至列表页面
request.getRequestDispatcher("/listArticle.jsp").forward(request, response);
}
ArticleService.java
public class ArticleService {
private ArticleDao articleDao=new ArticleDao();
private SolrjDao solrjDao=new SolrjDao();
/**
* @param artilce
* 添加商品
* 1、添加商品的时候,先将数据保存至数据库
* 2、将数据信息保存至索引库
* 3、如果数据保存时数据库以及索引库都正常的时候就提交事务
* @throws IOException
* @throws SolrServerException
*/
public void addArticle(Article article) throws SolrServerException, IOException {
//将数据保存至数据库,并获取该记录生成主键id值
String id = articleDao.saveArticle(article);
article.setId(id);
//将数据保存至索引库
solrjDao.saveArticle(article);
}
public List<Article> getAllArticleBykeyWork(String keyword) throws SolrServerException, IOException {
List<Article> articles = solrjDao.getAllArticleBykeyWork(keyword);
return articles;
}
}
SolrjDao.java
public class SolrjDao {
public void saveArticle(Article article) throws SolrServerException, IOException {
// 创建solrj客户端对象,通过该对象与solr应用交互
HttpSolrClient client = new HttpSolrClient.Builder("http://192.168.233.133:8983/solr/test_core")
.withConnectionTimeout(10000).build();
// 创建文档实例,一个文档实例代表一条记录
SolrInputDocument document = new SolrInputDocument();
// 通过SolrInputDocument指定列以及值的信息
// 通过UUID生成id值(id已存在,则更新)
String id = UUID.randomUUID().toString();
document.addField("id", id);
document.addField("title", article.getTitle());
document.addField("locality", article.getLocality());
document.addField("price", article.getPrice());
document.addField("create_date", article.getCreate_date());
client.add(document);
client.commit();
client.close();
}
public List<Article> getAllArticleBykeyWork(String keyword) throws SolrServerException, IOException {
HttpSolrClient client = new HttpSolrClient.Builder("http://192.168.233.133:8983/solr/test_core")
.withConnectionTimeout(10000).build();
// 创建solrjquery实例,通过这个对象可以设置查询的关键字 设置fl dl 高亮信息 分页等等
SolrQuery solrQuery = new SolrQuery();
// 设置查询关键字
solrQuery.setQuery(keyword);
// 设置查询属性
solrQuery.set("df", "locality");
// 过滤条件,设置要显示的属性
solrQuery.set("fl", "id,title,price,locality,create_date");
// 设置分页
// solrQuery.setStart(0);
// solrQuery.setRows(2);
// 设置过滤条件
solrQuery.set("fq", "price:[3000 TO *]");
// 设置高亮
solrQuery.setHighlight(true);
// 制定高亮的字段
solrQuery.addHighlightField("locality");
// 设置高亮相关格式
solrQuery.setHighlightSimplePre("<font color='red'>");
solrQuery.setHighlightSimplePost("</font>");
// 将solrQuery传入client进行查询
QueryResponse queryResponse = client.query(solrQuery);
// 获取普通结果集
SolrDocumentList solrDocumentList = queryResponse.getResults();
// 获取高亮后的结果集
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
// 将查出的结果装入集合
List<Article> articles = new ArrayList<>();
// 通过forEach遍历获取每一条记录数
for (SolrDocument doc : solrDocumentList) {
Article article = new Article();
// 高亮前的效果
String id = (String) doc.get("id");
article.setId(id);
String title = (String) doc.get("title");
article.setTitle(title);
float PRICE = (float) doc.get("price");
article.setPrice(PRICE);
Date CREATE_DATE = (Date) doc.get("create_date");
article.setCreate_date(CREATE_DATE);
String LOCALITY = (String) doc.get("locality");
System.out.println("id:" + id + "title" + title + "price" + PRICE + "create_date" + CREATE_DATE + "locality"
+ LOCALITY);
// 获取高亮后的数据
Map<String, List<String>> docMaps = highlighting.get(id);
String LOCALITY1 = docMaps.get("locality").get(0);
article.setLocality(LOCALITY == null ? LOCALITY : LOCALITY1);
articles.add(article);
}
return articles;
}
}
ArticleDao.java
public class ArticleDao {
public String saveArticle(Article article) {
// TODO Auto-generated method stub
// 将数据保存至数据库 可以通过 jdbc mybatis Hibernate等技术来实现,再返回主键id值
// 生成id值
String id = UUID.randomUUID().toString();
return id;
}
}
至此完结