文档章节

5. SolrJ的基本使用

戴征淼
 戴征淼
发布于 2017/04/15 11:20
字数 1762
阅读 103
收藏 0

1. 使用maven构建solr开发环境

  1. pom.xml:solr和solrj的版本最好一致,由于solr使用slf4j的包进行日志输出,可以需要添加slf4j-log4j12的依赖(别忘了log4j.properties配置文件,这个文件在solr解压后的server/resources目录下就有)。
<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>3.8.1</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.apache.solr</groupId>
		<artifactId>solr-solrj</artifactId>
		<version>5.5.4</version>
	</dependency>
	<dependency>
		<groupId>org.slf4j</groupId>
		<artifactId>slf4j-log4j12</artifactId>
		<version>1.6.6</version>
	</dependency>
</dependencies>

2. SolrClient

  1. SolrClient(public abstract class SolrClient implements Serializable, Closeable),这是一个abstract类,Solr的操作基本上都是基于这个类完成,主要用到的有HttpSolrClient(单机版就用这个),CloudSolrClient(solrCloud集群用这个)。SolrServer现在已经不建议使用了。

  2. HttpSolrClient:创建时指定solr的地址以及collection(路由的最后一段路径)即可(collection也可以不指定,在操作索引时自己将collection带上)


public static final String SOLR_HOST = "http://127.0.0.1:8080/solr/solrJDemo";
SolrClient solrClient = new HttpSolrClient(SOLR_HOST);

  1. CloudSolrClient:单机solr直接指定solr的Host即可,而solr集群已经交给zookeeper处理,请求会交给zookeeper,zookeeper再来决定哪个solr节点来处理请求,故我们只需要指定zookeeper的host就可以了。然后和HttpSolrClient一样,可以设置默认的collection
public static final String ZK_HOST = "192.168.4.41:2181,192.168.4.41:2281,192.168.4.41:2381";

//zkHost列表
CloudSolrClient solrClient = new CloudSolrClient(ZK_HOST);

//设置默认的Collection
solrClient.setDefaultCollection("shardCollection01");

2. 添加/更新、删除索引

  1. 添加/更新索引(SolrInputDocument):solr中添加一个document,没有的就添加,有对应的id就会更新,索引用的是同一个方法add()及它重载的方法,有很多(当然就包括设置collection的方法了):下面这个例子用的就是SolrInputDocument进行添加/更新索引。注意不要玩commit()提交
public static void addDocs() {
	String[] words = { "中央全面深化改革领导小组", "第四次会议", "审议了国企薪酬制度改革", "考试招生制度改革", "传统媒体与新媒体融合等", "相关内容文件", "习近平强调要", "逐步规范国有企业收入分配秩序", "实现薪酬水平适当",
			"结构合理、管理规范、监督有效", "对不合理的偏高", "过高收入进行调整", "深化考试招生制度改革", "总的目标是形成分类考试", "综合评价", "多元录取的考试招生模式", "健全促进公平", "科学选才", "监督有力的体制机制", "着力打造一批形态多样",
			"手段先进", "具有竞争力的新型主流媒体", "建成几家拥有强大实力和传播力", "公信力", "影响力的新型媒体集团" };
	long start = System.currentTimeMillis();
	System.err.println("-------》开始添加索引《----------");
	List<SolrInputDocument> docs = new ArrayList<SolrInputDocument>();
	for (int i = 1; i <= 30000; i++) {
		SolrInputDocument document   = new SolrInputDocument();
		document.addField("id", "id"+i,1.0f);
		document.addField("name", words[1%21]);
		document.addField("price", Math.random()*1000);
		
		docs.add(document);
	}
	
	SolrClient solrClient = new HttpSolrClient(SOLR_HOST);
	try {
	/*	solrClient.add(docs);//2971
		solrClient.commit();*/
		
	/*	UpdateRequest request = new UpdateRequest();//4273,3321,3659
		request.setAction(ACTION.COMMIT, false, false);
		request.add(docs);
		request.process(solrClient);*/
		
		solrClient.add(docs.iterator());//3724
		solrClient.commit();
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	System.out.println("time elapsed(ms):"+ (System.currentTimeMillis() - start));
	System.err.println("-------》添加结束《----------");
}
  1. 添加/更新索引(POJO):我们不仅可以构建SolrInputDocument往solr里面添加索引,也可以直接把POJO添加索引库里面去。POJO的属性需要使用Field进行注解,同时POJO的属性必须是schema.xml文件中定义的属性,例如relatedLinks属性,就不是schema.xml中的域,但是使用@Field("links")注解后可以添加的,因为links是schema.xml已经定义过的域(允许多值的),添加到solr后这个属性是links,而不是relatedLinks。
public class NewsBean {

	@Field
	private String id;
	
	@Field
	private String name;
	
	@Field
	private String author;
	
	@Field
	private String description;
	
	@Field("links")
	private List<String> relatedLinks;
	
	//setter,getter方法
	
}
public static void addBeans() {
	String[] words = { "中央全面深化改革领导小组", "第四次会议", "审议了国企薪酬制度改革", "考试招生制度改革",
			"传统媒体与新媒体融合等", "相关内容文件", "习近平强调要", "逐步规范国有企业收入分配秩序",
			"实现薪酬水平适当", "结构合理、管理规范、监督有效", "对不合理的偏高", "过高收入进行调整",
			"深化考试招生制度改革", "总的目标是形成分类考试", "综合评价", "多元录取的考试招生模式", "健全促进公平",
			"科学选才", "监督有力的体制机制", "着力打造一批形态多样", "手段先进", "具有竞争力的新型主流媒体",
			"建成几家拥有强大实力和传播力", "公信力", "影响力的新型媒体集团" };
	
	System.err.println("-------》开始添加索引《----------");
	long start = System.currentTimeMillis();
	List<NewsBean> beans = new ArrayList<NewsBean>();
	
	for(int i =1;i<=3000;i++) {
		NewsBean newsBean = new NewsBean();
		newsBean.setId("id"+i);
		newsBean.setName("news"+i);
		newsBean.setAuthor(getAuthors());
		newsBean.setDescription(words[i%21]);
		newsBean.setRelatedLinks(getLinks());
		
//			DocumentObjectBinder binder = new DocumentObjectBinder();
//			SolrInputDocument document = binder.toSolrInputDocument(newsBean);
		
		beans.add(newsBean);
	}

	SolrClient solrClient = new HttpSolrClient(SOLR_HOST);
	try {
		solrClient.addBeans(beans.iterator());
		solrClient.commit();
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	
	System.out.println("time elapsed(ms):"+ (System.currentTimeMillis() - start));
	System.err.println("-------》添加结束《----------");
}

public static String getAuthors() {
	List<String> list = Arrays.asList(authors).subList(0, rand.nextInt(3));
	String str = "";
	for (String tmp : list) {
		str += " " + tmp;
	}
	return str;
}

public static List<String> getLinks() {
	return Arrays.asList(links).subList(0, rand.nextInt(5));
}
  1. 删除索引:删除索引用的是deleteById()和deleteByQuery()两个方法
public static void deleteDoc() {
	SolrClient solrClient = new HttpSolrClient(SOLR_HOST);
	try {
	//	solrClient.deleteByQuery("id:id1");//根据条件查询
//			solrClient.deleteById("id2");
		solrClient.deleteById(Arrays.asList("id2","id3","id4"));
		solrClient.commit();
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	System.out.println("---->");
}

3. 查询

  1. 使用SolrDocument处理查询结果:solr查询,比较常用的方法是,构建一个SolrQuery对象,然后solrClient调用query(SolrQuery query)方法得到QueryResponse响应对象,然后进行处理
  • SolrQuery:setQuery对应的solr控制台q查询条件,这个是必填的;setFilterQueries()筛选条件;setSort()排序条件;setStart(),setRows()是分页;setFields()是需要查询的列;setHighlight(),addHighlightField(),setHighlightSimplePre(),setHighlightSimplePost()几个方法就是处理高亮的,很容易和控制台对应起来

  • QueryResponse:常见的有status(状态,0表示成功),还有结果集getResults(),getHighlighting()高亮的结果集等等

public static void queryDemo() {
		
	SolrClient solrClient = new HttpSolrClient(SOLR_HOST);
	
	SolrQuery query = new SolrQuery();
	query.setQuery("description:合理");

	//	query.setFilterQueries(fq);//筛选

	query.setSort("id", org.apache.solr.client.solrj.SolrQuery.ORDER.desc);//设置排序条件

	query.setStart(0);//分页
	query.setRows(20);//分页
	
//		query.setFields("id","name","author","description");//查询的列
	
	//设置高亮,pre和post表示高亮的处理,例如搜索到河里
	query.setHighlight(true);
	query.addHighlightField("description");//添加高亮的字段
	query.setHighlightSimplePre("<em>");
	query.setHighlightSimplePost("</em>");
	
	try {
		QueryResponse response = solrClient.query(query);
		System.out.println(response);
		// 搜索得到的结果数
		System.out.println("Find:" + response.getResults().getNumFound());
		// 输出结果
		int iRow = 1;
		for (SolrDocument doc : response.getResults()) {
			
			System.out.println("----------" + iRow + "------------");
			System.out.println("id: " + doc.getFieldValue("id").toString());
			System.out.println("name: " + doc.getFieldValue("name").toString());
			System.out.println("author: "+ doc.getFieldValue("author").toString());
			System.out.println("description: " + doc.getFieldValue("description"));
			System.out.println("links: " + doc.getFieldValue("links"));
			iRow++;
		}
		
		System.out.println(response.getHighlighting());
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}
	
  1. QueryResponse结果集也是可以直接转换成POJO对象,然后进行处理的,使用getBeans(POJO.class)
public static void queryPoJoDemo() {
		
	SolrClient solrClient = new HttpSolrClient(SOLR_HOST);
	
	SolrQuery query = new SolrQuery();
	query.setQuery("description:合理");

	//	query.setFilterQueries(fq);//筛选

	query.setSort("id", org.apache.solr.client.solrj.SolrQuery.ORDER.desc);//设置排序条件

	query.setStart(0);//分页
	query.setRows(20);//分页
	
//		query.setFields("id","name","author","description");//查询的列
	
	//设置高亮,pre和post表示高亮的处理,例如搜索到河里
	query.setHighlight(true);
	query.addHighlightField("description");//添加高亮的字段
	query.setHighlightSimplePre("<em>");
	query.setHighlightSimplePost("</em>");
	
	try {
		QueryResponse response = solrClient.query(query);
		System.out.println(response);
		// 搜索得到的结果数
		System.out.println("Find:" + response.getResults().getNumFound());
		// 输出结果
		int iRow = 1;
		for (NewsBean news : response.getBeans(NewsBean.class)) {
			
			System.out.println("----------" + iRow + "------------");
			System.out.println("id: " + news.getId());
			System.out.println("name: " + news.getName());
			System.out.println("author: "+ news.getAuthor());
			System.out.println("description: " + news.getDescription());
			System.out.println("links: " + news.getRelatedLinks());
			iRow++;
		}
		
		System.out.println(response.getHighlighting());
	} catch (SolrServerException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
}

© 著作权归作者所有

戴征淼
粉丝 0
博文 6
码字总数 7228
作品 0
深圳
程序员
私信 提问
Apache Solr 之 使用SolrJ操作索引库

Solrj是Solr搜索服务器的一个比较基础的客户端工具,可以非常方便地与Solr搜索服务器进行交互。最基本的功能就是管理Solr索引,包括添加、更新、删除和查询等。对于一些比较基础的应用,用S...

空云万里晴
2014/12/09
0
1
Solr JAVA客户端SolrJ 4.9使用示例教程

简介 SolrJ是操作Solr的JAVA客户端,它提供了增加、修改、删除、查询Solr索引的JAVA接口。SolrJ针对Solr提供了Rest 的HTTP接口进行了封装,SolrJ底层是通过使用httpClient中的方法来完成Sol...

cloud-coder
2014/08/21
0
0
Solr 按日期facet 差8小时问题解决

项目中使用solrj来操作solr,日期solr会自动转换: 1.solrj在提交到solr时,时间会因为时区问题减少八小时 2.solr接收到时间后,存为底层lucene索引时时间类型为long型,是正确的时区时间,但...

zachary124
2014/06/24
0
4
有关solr的一些不明白的地方,希望得到大家的解答

最近在学习solr的使用,但是有一些不理解的地方希望在这方面了解的人能给我一些解答,非常的感谢。 第一:solr的高亮,在使用solrJ时,resp.getHighlighting().get(id).get("content")进行高...

BravoZu
2012/07/31
244
0
有关solr的一些不明白的地方,希望得到你的回答

@红薯 你好,想跟你请教个问题:因为没有人回答,因此来向您请教,打扰您了,希望得到你的回答 第一:solr的高亮,在使用solrJ时,resp.getHighlighting().get(id).get("content")进行高亮,...

BravoZu
2012/08/01
614
0

没有更多内容

加载失败,请刷新页面

加载更多

《生活的难题》的读后感3600字范文

《生活的难题》的读后感3600字范文: 假如我们对丑的事物也能够像对待美的事物那般抱持一种开放、接纳的心态,拥有相同的感受力,那么我们便会发现它们都是充满意义的,而这种认识会使生活变...

原创小博客
28分钟前
1
0
Linux learn(四)

7. Linux磁盘与文件系统管理 文件系统通常会将数据放在不同的区块,权限与属性放置到inode中,至于实际数据则放到datab lock区块中,另外,还有一个超级区块(superblock)会记录整个文件系统...

lazy~
36分钟前
1
0
微信公众号开发(四)

微信公众号开发时常需要一个用户授权绑定的过程。关于微信公众号的用户绑定,一般有如下两种实现方式: (1)通过发送短信验证码的方式; (2)使用用户登录时,向后端传递openid的方式。 使...

织梦之魂
今天
4
0
设计模式-工厂模式

工厂模式 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 在工厂模式中,我们在创建对象时不会对客户端...

HOT_POT
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部