前面几节我们对 Solr 的运行有了个大概的了解,本文将介绍如何通过操作 API 来实现前面 web 控制台演示的那些功能的。
创建 Java 项目
使用 eclipse 新建一个 Java 项目,导入 apache-tomcat-7.0.42\webapps\solr\WEB-INF\lib 下面所有的 jar 包,再添加一个 junit4.8.1 的 jar 包
新建一个测试类
废话不多说,直接上代码,API 操作还是比较简单的,就不分开说了。
SolrTest.java
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrQuery.ORDER;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.FacetField;
import org.apache.solr.client.solrj.response.FacetField.Count;
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;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class SolrTest {
private static String url = "http://localhost:8080/solr/test";
private SolrClient client;
@Before
public void init() {
client = new HttpSolrClient(url);
}
@After
public void destroy() {
client = null;
}
// 单文档插入
public void addDoc() throws Exception {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", 10000001);
doc.addField("name", "Solr Input Document");
doc.addField("manu", "this is SolrInputDocument content");
client.add(doc);
client.commit();
}
// 批量文档插入
public void addDocList() throws Exception {
Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
for (int i = 1; i < 11; i++) {
SolrInputDocument doc = new SolrInputDocument();
doc.addField("id", 1000000 + i);
doc.addField("name", "batch solr document insert " + i);
doc.addField("manu", "batch solr document content insert " + i);
docs.add(doc);
}
client.add(docs);
client.commit();
}
@Test
// 单个文档对应的 Java Bean 插入
public void addDocBean() throws Exception {
Index doc = new Index();
doc.setId("100000000");
doc.setName("add bean document");
doc.setManu("index bean manu 中文测试");
doc.setCat(new String[] { "a1", "b2" });
client.addBean(doc);
client.commit();
}
// 批量文档 Bean 插入
public void addDocBeanList() throws Exception {
Collection<Index> docs = new ArrayList<Index>();
for (int i = 1; i < 11; i++) {
Index doc = new Index();
doc.setId("10000000" + i);
doc.setName("add bean document " + i);
doc.setManu("bean document manu " + i);
docs.add(doc);
}
client.addBeans(docs);
client.commit();
}
// 根据 id 删除单个文档
public void remove() throws Exception {
client.deleteById("100000000");
client.commit();
}
// 根据批量 id 删除文档
public void removeList() throws Exception {
List<String> ids = new ArrayList<String>();
for (int i = 1; i < 6; i++) {
ids.add("10000000" + i);
}
client.deleteById(ids);
client.commit();
}
// 根据查询条件删除文档
public void removeByQuery() throws Exception {
client.deleteByQuery("id:100000007");
client.commit();
}
// 查询操作
public void queryAll() throws Exception {
SolrQuery query = new SolrQuery();
query.set("q", "*:*");
query.setStart(0);
query.setRows(Integer.MAX_VALUE);
// query.set("start", 0);
// query.set("row", Integer.MAX_VALUE);
query.set("id", "id desc");
query.set("fl", "*, score");
QueryResponse response = client.query(query);
SolrDocumentList docs = response.getResults();
for (SolrDocument doc : docs) {
log(doc);
}
}
// 一些附属操作
public void otherMethod() throws Exception {
client.getBinder();
client.optimize(); // 合并索引文件,可以优化索引、提供性能,但需要一定的时间
client.ping(); // ping服务器是否连接成功
client.rollback();
client.commit();
}
// query 基本用法测试
public void queryCase() {
// AND 并且
SolrQuery params = new SolrQuery("name:apple AND manu:inc");
// OR 或者
params.setQuery("name:apple OR manu:apache");
// 空格 等同于 OR
params.setQuery("name:server manu:dell");
// params.setQuery("name:solr - manu:inc");
// params.setQuery("name:server + manu:dell");
// 查询name包含solr apple
params.setQuery("name:solr,apple");
// manu不包含inc
params.setQuery("name:solr,apple NOT manu:inc");
// 50 <= price <= 200
params.setQuery("price:[50 TO 200]");
params.setQuery("popularity:[5 TO 6]");
// 50 <= price <= 200 AND 5 <= popularity <= 6
params.setQuery("price:[50 TO 200] AND popularity:[5 TO 6]");
params.setQuery("price:[50 TO 200] OR popularity:[5 TO 6]");
// 过滤器查询,可以提高性能 filter 类似多个条件组合,如and
// params.addFilterQuery("id:VA902B");
// params.addFilterQuery("price:[50 TO 200]");
// params.addFilterQuery("popularity:[* TO 5]");
// params.addFilterQuery("weight:*");
// 0 < popularity < 6 没有等于
// params.addFilterQuery("popularity:{0 TO 6}");
// 排序
params.addSort("id", ORDER.asc);
// 分页:start开始页,rows每页显示记录条数
// params.add("start", "0");
// params.add("rows", "200");
// params.setStart(0);
// params.setRows(200);
// 设置高亮
params.setHighlight(true); // 开启高亮组件
params.addHighlightField("name");// 高亮字段
params.setHighlightSimplePre("<font color='red'>");// 标记,高亮关键字前缀
params.setHighlightSimplePost("</font>");// 后缀
params.setHighlightSnippets(1);// 结果分片数,默认为1
params.setHighlightFragsize(1000);// 每个分片的最大长度,默认为100
// 分片信息
params.setFacet(true).setFacetMinCount(1).setFacetLimit(5)// 段
.addFacetField("name")// 分片字段
.addFacetField("inStock");
// params.setQueryType("");
try {
QueryResponse response = client.query(params);
/*
* List<Index> indexs = response.getBeans(Index.class); for (int i =
* 0; i < indexs.size(); i++) { fail(indexs.get(i)); }
*/
// 输出查询结果集
SolrDocumentList list = response.getResults();
log("query result nums: " + list.getNumFound());
for (int i = 0; i < list.size(); i++) {
log(list.get(i));
}
// 输出分片信息
List<FacetField> facets = response.getFacetFields();
for (FacetField facet : facets) {
log(facet);
List<Count> facetCounts = facet.getValues();
for (FacetField.Count count : facetCounts) {
System.out.println(count.getName() + ": "
+ count.getCount());
}
}
} catch (SolrServerException e) {
e.printStackTrace();
}
}
// 分片查询, 可以统计关键字及出现的次数、或是做自动补全提示
public void facetQueryCase() {
SolrQuery params = new SolrQuery("*:*");
// 排序
params.addSort("id", ORDER.asc);
params.setStart(0);
params.setRows(200);
// Facet为solr中的层次分类查询
// 分片信息
params.setFacet(true).setQuery("*:*").setFacetMinCount(1)
.setFacetLimit(5) // 段
// .setFacetPrefix("electronics", "cat")
.setFacetPrefix("cor") // 查询manu、name中关键字前缀是cor的
.addFacetField("manu").addFacetField("name"); // 分片字段
try {
QueryResponse response = client.query(params);
// 输出查询结果集
SolrDocumentList list = response.getResults();
log("Query result nums: " + list.getNumFound());
for (int i = 0; i < list.size(); i++) {
log(list.get(i));
}
log("All facet filed result: ");
// 输出分片信息
List<FacetField> facets = response.getFacetFields();
for (FacetField facet : facets) {
log(facet);
List<Count> facetCounts = facet.getValues();
for (FacetField.Count count : facetCounts) {
// 关键字 - 出现次数
log(count.getName() + ": " + count.getCount());
}
}
log("Search facet [name] filed result: ");
// 输出分片信息
FacetField facetField = response.getFacetField("name");
List<Count> facetFields = facetField.getValues();
for (Count count : facetFields) {
// 关键字 - 出现次数
log(count.getName() + ": " + count.getCount());
}
} catch (SolrServerException e) {
e.printStackTrace();
}
}
private void log(Object obj) {
System.out.println(obj);
}
}
里面用到一个 java bean Index.java
,代码如下:
import org.apache.solr.client.solrj.beans.Field;
public class Index {
@Field
private String id;
@Field
private String name;
@Field
private String manu;
@Field
private String[] cat;
@Field
private String[] features;
@Field
private float price;
@Field
private int popularity;
@Field
private boolean inStock;
public String getId() {
return id;
}
@Field
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getManu() {
return manu;
}
public void setManu(String manu) {
this.manu = manu;
}
public String[] getCat() {
return cat;
}
public void setCat(String[] cat) {
this.cat = cat;
}
public String[] getFeatures() {
return features;
}
public void setFeatures(String[] features) {
this.features = features;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public int getPopularity() {
return popularity;
}
public void setPopularity(int popularity) {
this.popularity = popularity;
}
public boolean isInStock() {
return inStock;
}
public void setInStock(boolean inStock) {
this.inStock = inStock;
}
public String toString() {
return this.id + "#" + this.name + "#" + this.manu + "#" + this.cat;
}
}