昨天玩了下solr的web界面,在界面上对solr添加document和查询等等操作试了试
见:http://blog.csdn.net/qq_20641565/article/details/55103105
今天索性玩了下javaAPI操作solr。
试了下javaApi操作solr的增、删、常规查询、以及spell建议查询
- 工程结构:
- 1. pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>solr-test</groupId>
<artifactId>solr-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>5.5.3</version>
</dependency>
<dependency>
<groupId>jdk.tools</groupId>
<artifactId>jdk.tools</artifactId>
<version>1.7</version>
<scope>system</scope>
<systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 2. properties文件如下:
SOLR_URL=http://lijie:8983/solr
SOLR_CORE=lijie_test
- 3.Person类代码如下:
package com.lijie.solr;
import org.apache.solr.client.solrj.beans.Field;
/**
* Person bean
*
* @author Lijie
*
*/
public class Person {
private String id;
private String name;
private int age;
private String addr;
public String getId() {
return id;
}
@Field
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
@Field
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
@Field
public void setAge(int age) {
this.age = age;
}
public String getAddr() {
return addr;
}
@Field
public void setAddr(String addr) {
this.addr = addr;
}
public Person(String id, String name, int age, String addr) {
super();
this.id = id;
this.name = name;
this.age = age;
this.addr = addr;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", addr=" + addr + "]";
}
}
4.主类SolrMain代码如下:
package com.lijie.solr;
import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Collation;
import org.apache.solr.client.solrj.response.SpellCheckResponse.Correction;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
public class SolrMain {
/**
* solr http服务地址
*/
public static String SOLR_URL;
/**
* solr的core
*/
public static String SOLR_CORE;
static {
Properties properties = new Properties();
String path = SolrMain.class.getResource("/").getFile().toString()
+ "solr.properties";
try {
FileInputStream fis = new FileInputStream(new File(path));
properties.load(fis);
SOLR_URL = properties.getProperty("SOLR_URL");
SOLR_CORE = properties.getProperty("SOLR_CORE");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 主函数入口
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 1.测试插入文档
Map<String, String> map = new HashMap<String, String>();
map.put("id", "00001");
map.put("name", "lijie");
map.put("age", "24");
map.put("addr", "深圳");
addDocument(map, SOLR_CORE);
// 2.通过bean添加document
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("00002", "lisi", 25, "重庆"));
persons.add(new Person("00003", "wangwu", 26, "上海"));
addDocumentByBean(persons, SOLR_CORE);
// 3.根据id集合删除索引
List<String> ids = new ArrayList<String>();
ids.add("00001");
ids.add("00002");
ids.add("00003");
deleteDocumentByIds(ids, SOLR_CORE);
// 4.查询
getDocument(SOLR_CORE);
// 5.spell测试
getSpell(SOLR_CORE);
}
/**
* 获取solr服务
*
* @return
*/
private static HttpSolrClient getSolrClient(String core) {
HttpSolrClient hsc = new HttpSolrClient(SOLR_URL + core);
return hsc;
}
/**
* 添加文档
*
* @param map
* @param core
* @throws Exception
*/
private static void addDocument(Map<String, String> map, String core)
throws Exception {
SolrInputDocument sid = new SolrInputDocument();
for (Entry<String, String> entry : map.entrySet()) {
sid.addField(entry.getKey(), entry.getValue());
}
HttpSolrClient solrClient = getSolrClient("/" + core);
solrClient.add(sid);
commitAndCloseSolr(solrClient);
}
/**
* 添加文档,通过bean方式
*
* @param persons
* @param core
* @throws Exception
*/
private static void addDocumentByBean(List<Person> persons, String core)
throws Exception {
HttpSolrClient solrClient = getSolrClient("/" + core);
solrClient.addBeans(persons);
commitAndCloseSolr(solrClient);
}
/**
* 根据id集合删除索引
*
* @param ids
* @param core
* @throws Exception
*/
private static void deleteDocumentByIds(List<String> ids, String core)
throws Exception {
HttpSolrClient solrClient = getSolrClient("/" + core);
solrClient.deleteById(ids);
commitAndCloseSolr(solrClient);
}
private static void getDocument(String core) throws Exception {
HttpSolrClient solrClient = getSolrClient("/" + core);
SolrQuery sq = new SolrQuery();
// q查询
sq.set("q", "id:00003");
// filter查询
sq.addFilterQuery("id:[0 TO 00003]");
// 排序
sq.setSort("id", SolrQuery.ORDER.asc);
// 分页 从第0条开始取,取一条
sq.setStart(0);
sq.setRows(1);
// 设置高亮
sq.setHighlight(true);
// 设置高亮的字段
sq.addHighlightField("name");
// 设置高亮的样式
sq.setHighlightSimplePre("<font color='red'>");
sq.setHighlightSimplePost("</font>");
QueryResponse result = solrClient.query(sq);
// 这里可以从result获得查询数据(两种方式如下)
// 1.获取document数据
System.out.println("1.获取document数据-------------------------");
SolrDocumentList results = result.getResults();
// 获取查询的条数
System.out.println("一共查询到" + results.getNumFound() + "条记录");
for (SolrDocument solrDocument : results) {
System.out.println("id:" + solrDocument.get("id"));
System.out.println("name:" + solrDocument.get("name"));
System.out.println("age:" + solrDocument.get("age"));
System.out.println("addr:" + solrDocument.get("addr"));
}
// 2.获取对象信息,需要传入对应对象的类class
System.out.println("2.获取对象信息,需要传入对应对象的类class-----------");
List<Person> persons = result.getBeans(Person.class);
System.out.println("一共查询到" + persons.size() + "条记录");
for (Person person : persons) {
System.out.println(person);
}
commitAndCloseSolr(solrClient);
}
/**
* 查询使用spell接口,输入错误,solr可以给出建议词
*
* @param core
* @throws Exception
*/
private static void getSpell(String core) throws Exception {
HttpSolrClient solrClient = getSolrClient("/" + core);
SolrQuery sq = new SolrQuery();
sq.set("qt", "/spell");
// 原本是lisi,这里拼写错误,测试solr返回建议词语
sq.set("q", "liss");
QueryResponse query = solrClient.query(sq);
SolrDocumentList results = query.getResults();
// 获取查询条数
long count = results.getNumFound();
// 判断是否查询到
if (count == 0) {
SpellCheckResponse spellCheckResponse = query
.getSpellCheckResponse();
List<Collation> collatedResults = spellCheckResponse
.getCollatedResults();
for (Collation collation : collatedResults) {
long numberOfHits = collation.getNumberOfHits();
System.out.println("建议条数为:" + numberOfHits);
List<Correction> misspellingsAndCorrections = collation
.getMisspellingsAndCorrections();
for (Correction correction : misspellingsAndCorrections) {
String source = correction.getOriginal();
String current = correction.getCorrection();
System.out.println("推荐词语为:" + current + "原始的输入为:" + source);
}
}
} else {
for (SolrDocument solrDocument : results) {
// 获取key集合
Collection<String> fieldNames = solrDocument.getFieldNames();
// 根据key集合输出value
for (String field : fieldNames) {
System.out.println("key: " + field + ",value: "
+ solrDocument.get(field));
}
}
}
// 关闭连接
commitAndCloseSolr(solrClient);
}
/**
* 提交以及关闭服务
*
* @param solrClient
* @throws Exception
*/
private static void commitAndCloseSolr(HttpSolrClient solrClient)
throws Exception {
solrClient.commit();
solrClient.close();
}
}
- 遇到的问题:
一. 在执行solrClient.addBeans(persons);的时候报错,需要在Person类中添加@Field注解
二. 在执行result.getBeans(Person.class);做查询操作的时候,报了异常,查询说需要在solr的schema中要有对应字段的设置,但是我查看文件发现有设置这几个字段,这个问题暂时还不知道怎么解决,先留在这:
错误信息如下:
Exception in thread "main" org.apache.solr.client.solrj.beans.BindingException: Could not instantiate object of class com.lijie.solr.Person
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:71)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBeans(DocumentObjectBinder.java:50)
at org.apache.solr.client.solrj.response.QueryResponse.getBeans(QueryResponse.java:632)
at com.lijie.solr.SolrMain.getDocument(SolrMain.java:181)
at com.lijie.solr.SolrMain.main(SolrMain.java:76)
Caused by: org.apache.solr.client.solrj.beans.BindingException: Exception while setting value : [wangwu] on private java.lang.String com.lijie.solr.Person.name
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:457)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.inject(DocumentObjectBinder.java:440)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder.getBean(DocumentObjectBinder.java:67)
... 4 more
Caused by: java.lang.IllegalArgumentException: Can not set java.lang.String field com.lijie.solr.Person.name to java.util.ArrayList
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(Unknown Source)
at java.lang.reflect.Field.set(Unknown Source)
at org.apache.solr.client.solrj.beans.DocumentObjectBinder$DocField.set(DocumentObjectBinder.java:451)
... 6 more
- 解决问题
刚才解决了上面遇到的问题,当用@Field注解的时候,使用solrClient.addBeans(persons)方法,它会自动帮你在managed-schema文件中添加上对应插入字段的field标签,但是它添加的field的type是strings tlongs如下图:
但是我自己是添加的string和int类型的,索性自己修改了type为string和int,如下图:
然后在测试插入和删除,就没有报上面的异常了,看来managed-schema文件还是先自己配置好然后再进行操作比较保险。
查询结果如下: