Solr的基本使用
3 solr基本使用
3.1 schema.xml
schema.xml文件在SolrCore的conf目录下,它是Solr数据表配置文件,在此配置文件中定义了域以及域的类型还有其他一些配置,在solr中域必须先定义后使用。
3.1.1 field
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
Name:域的名称
Type:域的类型
Indexed:是否索引
Stored:是否存储
Required:是否必须
multiValued:是否是多值,存储多个值时设置为true,solr允许一个Field存储多个值,比如存储一个用户的好友id(多个),商品的图片(多个,大图和小图)
3.1.2 fieldType(域类型)
<fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<!-- in this example, we will only use synonyms at query time
<filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/>
-->
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzer type="query">
<tokenizer class="solr.StandardTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
<filter class="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
name:域类型的名称
class:指定域类型的solr类型。
analyzer:指定分词器。在FieldType定义的时候最重要的就是定义这个类型的数据在建立索引和进行查询的时候要使用的分析器analyzer,包括分词和过滤。
type:index和query。Index 是创建索引,query是查询索引。
tokenizer:指定分词器
filter:指定过滤器
3.1.3 uniqueKey
<uniqueKey>id</uniqueKey>
相当于主键,每个文档中必须有一个id域。
3.1.4 copyField(复制域)
<copyField source="cat" dest="text" />
可以将多个Field复制到一个Field中,以便进行统一的检索。当创建索引时,solr服务器会自动的将源域的内容复制到目标域中。
source:源域
dest:目标域,搜索时,指定目标域为默认搜索域,可以提供查询效率。
定义目标域:
必须要使用:multiValued=”true”
3.1.5 dynamicField(动态域)
Name:动态域的名称,是一个表达式,*匹配任意字符,只要域的名称和表达式的规则能够匹配就可以使用。
例如:搜索时查询条件【product_i:钻石】就可以匹配这个动态域,可以直接使用,不用单独再定义一个product_i域。
3.2 配置中文分析器
使用IKAnalyzer中文分析器。
第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。
第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classpath下。
第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。
<!-- IKAnalyzer-->
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
第四步:定义field,指定field的type属性为text_ik
<!--IKAnalyzer Field-->
<field name="title_ik" type="text_ik" indexed="true" stored="true" />
<field name="content_ik" type="text_ik" indexed="true" stored="false" multiValued="true"/>
第五步:重启tomcat
测试:
3.3 配置业务field
3.3.1 需求
要使用solr实现电商网站中商品搜索。
电商中商品信息在mysql数据库中存储了,将mysql数据库中数据在solr中创建索引。
需要在solr的schema.xml文件定义商品Field。
3.3.2 定义步骤
先确定定义的商品document的field有哪些?
可以根据mysql数据库中商品表的字段来确定:
products商品表:
商品document的field包括:pid、name、catalog、catalog_name、price、description、picture
先定义Fieldtype:
solr本身提供的fieldtype类型够用了不用定义新的了。
再定义Field:
pid:商品id主键
使用solr本身提供的:
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />
name:商品名称
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
catalog:商品分类
<field name="product_catalog" type="string" indexed="true" stored="true"/>
catalog_name:商品分类名称
<field name="product_catalog_name" type="text_ik" indexed="true" stored="true"/>
price:商品价格
<field name="product_price" type="float" indexed="true" stored="true"/>
description:商品描述
<field name="product_description" type="text_ik" indexed="true" stored="false"/>
picture:商品图片
<field name="product_picture" type="string" indexed="false" stored="true"/>
<!--product-->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_catalog" type="string" indexed="true" stored="true"/>
<field name="product_catalog_name" type="string" indexed="true" stored="true" />
<field name="product_price" type="float" indexed="true" stored="true"/>
<field name="product_description" type="text_ik" indexed="true" stored="false" />
<field name="product_picture" type="string" indexed="false" stored="true" />
<field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
3.4 dataimportHandler插件
3.4.1 第一步:添加jar包
Dataimport的jar
从solr-4.10.3\dist目录下拷贝solr-dataimporthandler-4.10.3.jar,复制到以下目录:
修改schema.xml如下:
数据库驱动包
把mysql数据库驱动包,拷贝到以下目录:
修改schema.xml,如下:
3.4.2 第二步:配置solrconfig.xml,添加一个requestHandler
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>
3.4.3 第三步:创建一个data-config.xml
在collection1\conf\目录下创建data-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/solr"
user="root"
password="root"/>
<document>
<entity name="product" query="SELECT pid,name,catalog,catalog_name,price,description,picture FROM products ">
<field column="pid" name="id"/>
<field column="name" name="product_name"/>
<field column="catalog" name="product_catalog"/>
<field column="catalog_name" name="product_catalog_name"/>
<field column="price" name="product_price"/>
<field column="description" name="product_description"/>
<field column="picture" name="product_picture"/>
</entity>
</document>
</dataConfig>
3.4.4 第四步:重启tomcat
3.4.5 第五步:点击“execute”按钮导入数据
注意:到入数据前会先清空索引库,然后再导入。
4 Solrj的使用
4.1 什么是solrj
solrj是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务,如下图:
Solrj和图形界面操作的区别就类似于数据库中你使用jdbc和mysql客户端的区别一样。
4.2 需求
使用solrj调用solr服务实现对索引库的增删改查操作。
4.3 环境准备
Solr:4.10.3
Jdk环境:1.7.0_72(solr4.10 不能使用jdk1.7以下)
Ide环境:eclipse indigo
4.4 工程搭建
4.4.1 第一步:创建java工程
4.4.2 第二步:添加jar
Solrj的包
Solr服务的依赖包
4.5 代码实现
4.5.1 添加\修改索引
4.5.1.1 步骤
1、 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
2、 创建SolrInputDocument对象,然后通过它来添加域。
3、 通过HttpSolrServer对象将SolrInputDocument添加到索引库。
4、 提交。
4.5.1.2 代码
说明:根据id(唯一约束)域来更新Document的内容,如果根据id值搜索不到id域则会执行添加操作,如果找到则更新。
@Test
public void addDocument() throws Exception {
// 1、 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
// 参数:solr服务器的访问地址
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/");
// 2、 创建SolrInputDocument对象,然后通过它来添加域。
SolrInputDocument document = new SolrInputDocument();
// 第一个参数:域的名称,域的名称必须是在schema.xml中定义的
// 第二个参数:域的值
// 注意:id的域不能少
document.addField("id", "c0001");
document.addField("title_ik", "使用solrJ添加的文档");
document.addField("content_ik", "文档的内容");
document.addField("product_name", "商品名称");
// 3、 通过HttpSolrServer对象将SolrInputDocument添加到索引库。
server.add(document);
// 4、 提交。
server.commit();
}
4.5.1.3 查询测试
4.5.2 删除索引
4.5.2.1 根据ID删除
4.5.2.1.1 代码
@Test
public void deleteDocument() throws Exception {
// 1、 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
// 参数:solr服务器的访问地址
HttpSolrServer server = new HttpSolrServer(
"http://localhost:8080/solr/");
// 根据ID删除
server.deleteById("c0001");
// 提交
server.commit();
}
4.5.2.1.2 查询测试
4.5.2.2 根据条件删除
@Test
public void deleteDocumentByQuery() throws Exception {
// 1、 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
// 参数:solr服务器的访问地址
HttpSolrServer server = new HttpSolrServer(
"http://localhost:8080/solr/");
// 根据ID删除
server.deleteByQuery("id:c0001");
// 全部删除
// server.deleteByQuery("*:*");
// 提交
server.commit();
}
4.5.3 查询索引
4.5.3.1 solr的查询语法
1. q - 查询关键字,必须的,如果查询所有使用:。
请求的q是字符串
- fq - (filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如::
请求fq是一个数组(多个值)
过滤查询价格从1到20的记录。
也可以在“q”查询条件中使用product_price:[1 TO 20],如下:
也可以使用“*”表示无限,例如:
20以上:product_price:[20 TO *]
20以下:product_price:[* TO 20]
- sort - 排序,格式:sort=+
@Test
public void queryIndex() throws Exception {
// 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
// 参数:solr服务器的访问地址
HttpSolrServer server = new HttpSolrServer(
"http://localhost:8080/solr/");
// 创建SolrQuery对象
SolrQuery query = new SolrQuery();
// 设置查询条件,名称“q”是固定的且必须 的
query.set("q", "id:2");
// 调用server的查询方法,查询索引库
QueryResponse response = server.query(query);
// 查询结果
SolrDocumentList results = response.getResults();
// 查询结果总数
long cnt = results.getNumFound();
System.out.println("查询结果总数:" + cnt);
for (SolrDocument solrDocument : results) {
System.out.println(solrDocument.get("id"));
System.out.println(solrDocument.get("product_name"));
System.out.println(solrDocument.get("product_price"));
System.out.println(solrDocument.get("product_catalog_name"));
System.out.println(solrDocument.get("product_picture"));
}
}
4.5.3.3 复杂查询
复杂查询中包括高亮的处理
@Test
public void queryIndex2() throws Exception {
// 创建HttpSolrServer对象,通过它和Solr服务器建立连接。
// 参数:solr服务器的访问地址
HttpSolrServer server = new HttpSolrServer("http://localhost:8080/solr/");
// 创建SolrQuery对象
SolrQuery query = new SolrQuery();
// 设置查询条件
query.setQuery("钻石");
// 设置过滤条件
query.setFilterQueries("product_catalog_name:幽默杂货");
// 设置排序
query.setSort("product_price", ORDER.desc);
// 设置分页信息
query.setStart(0);
query.setRows(10);
// 设置显得的域的列表
query.setFields("id", "product_name", "product_price",
"product_catalog_name", "product_picture");
// 设置默认搜索域
query.set("df", "product_name");
// 设置高亮
query.setHighlight(true);
query.addHighlightField("product_name");
query.setHighlightSimplePre("<em>");
query.setHighlightSimplePost("</em>");
// 调用server的查询方法,查询索引库
QueryResponse response = server.query(query);
// 查询结果
SolrDocumentList results = response.getResults();
// 查询结果总数
long cnt = results.getNumFound();
System.out.println("查询结果总数:" + cnt);
for (SolrDocument solrDocument : results) {
System.out.println(solrDocument.get("id"));
String productName = (String) solrDocument.get("product_name");
//获取高亮列表
Map<String, Map<String, List<String>>> highlighting = response
.getHighlighting();
//获得本文档的高亮信息
List<String> list = highlighting.get(solrDocument.get("id")).get(
"product_name");
//如果有高亮,则把商品名称赋值为有高亮的那个名称
if (list != null) {
productName = list.get(0);
}
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"));
}
}