solrj作为solr的java客户端使得solr的开发简单了许多,solrJ实际上也是是封装了httpClient方法,来操作solr的API的。
下面来通过一个简单的demo实现solrj的索引创建以及查询
demo需求:需要对一个product 的实体创建以及查询索引(字段包括id,name,keywords,description,sn)
一,首先根据需要在solr配置文件schema.xml中配置相应的field(这边我只需要增加sn字段即可,其他都直接使用了默认存在的field)
<!-- for csop product <field name="id" type="string" indexed="true" stored="true" /> <field name="name" type="string" indexed="true" stored="true" /> <field name="keywords" type="string" indexed="true" stored="true" /> <field name="description" type="string" indexed="true" stored="true" /> --> <field name="sn" type="string" indexed="true" stored="true" /> <!-- for csop product over -->
二,创建测试项目
1.所需jar包
除了solrj的jar还需要一下jar
2.创建实体product
这里所有被添加Annotation @Field 注解的属性将参与index操作
package com.demo.solr.model; import org.apache.solr.client.solrj.beans.Field; public class Product { @Field private String id; @Field private String name; @Field private String keywords; @Field private String description; @Field private String sn; public Product() { super(); } public Product(String id, String name, String keywords, String description, String sn) { super(); this.id = id; this.name = name; this.keywords = keywords; this.description = description; this.sn = sn; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getKeywords() { return keywords; } public void setKeywords(String keywords) { this.keywords = keywords; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getSn() { return sn; } public void setSn(String sn) { this.sn = sn; } }
3.添加配置文件,用于创建solr连接的参数
solr.host=http://localhost:8983/solr/core_one solr.client.timeout=20000 solr.connect.timeout=5000 max.connections.perhost=100 max.total.connection=100
获取配置文件的javabean
package com.demo.solr.config; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; public class SolrConfig { private final static Logger logger = Logger.getLogger(SolrConfig.class); public static String solrHost; public static int solrConnectTimeout; public static int solrClientTimeout; public static int maxConnectionsPerHost; public static int maxTotalConnection; static { InputStream is = SolrConfig.class .getResourceAsStream("/solr.properties"); if (is != null) { Properties properties = new Properties(); try { properties.load(is); } catch (IOException e) { logger.error(e.getMessage(), e); e.printStackTrace(); } solrHost = properties.getProperty("solr.host"); String solrClientTimeoutStr = properties .getProperty("solr.client.timeout"); if (StringUtils.isNotEmpty(solrClientTimeoutStr)) { solrClientTimeout = Integer.parseInt(solrClientTimeoutStr); } String solrConnectTimeoutStr = properties .getProperty("solr.connect.timeout"); if (StringUtils.isNotEmpty(solrConnectTimeoutStr)) { solrConnectTimeout = Integer.parseInt(solrConnectTimeoutStr); } String maxConnectionsPerHostStr = properties .getProperty("max.connections.perhost"); if (StringUtils.isNotEmpty(maxConnectionsPerHostStr)) { maxConnectionsPerHost = Integer.parseInt(maxConnectionsPerHostStr); } String maxTotalConnectionStr = properties .getProperty("max.total.connection"); if (StringUtils.isNotEmpty(maxTotalConnectionStr)) { maxTotalConnection = Integer.parseInt(maxTotalConnectionStr); } } } }
4,配置product中自动对应的index name
随便写的 也没用enum
package com.demo.solr.config; public interface ISolrFields { String ID = "id"; String NAME = "name"; String KEYWORDS = "keywords"; String DESCRIPTION = "description"; String SN = "sn"; }
5,获取solrclient,这里我创建一个工具类来获取SolrClient
package com.demo.solr; import org.apache.solr.client.solrj.impl.HttpSolrClient; import com.demo.solr.config.SolrConfig; public class SolrClientFactory { private static HttpSolrClient solrClient = null; private static SolrClientFactory solrClientFactory = null; private static String solrHost = SolrConfig.solrHost; private static int solrClientTimeout = SolrConfig.solrClientTimeout; private static int solrConnectTimeout = SolrConfig.solrConnectTimeout; private static int maxConnectionsPerHost = SolrConfig.maxConnectionsPerHost; private static int maxTotalConnection = SolrConfig.maxTotalConnection; private SolrClientFactory() { } public synchronized HttpSolrClient getSolrClient() { if (solrClient == null) { solrClient = new HttpSolrClient(solrHost); solrClient.setSoTimeout(solrClientTimeout); // socket read timeout solrClient.setConnectionTimeout(solrConnectTimeout); solrClient.setDefaultMaxConnectionsPerHost(maxConnectionsPerHost); solrClient.setMaxTotalConnections(maxTotalConnection); solrClient.setFollowRedirects(false); // defaults to false //allowCompression defaults to false. //Server side must support gzip or deflate for this to have any effect. solrClient.setAllowCompression(true); } return solrClient; } public static synchronized SolrClientFactory getInstance() { if (solrClientFactory == null) { solrClientFactory = new SolrClientFactory(); } return solrClientFactory; } }
6,创建索引,只需要4步
a.将product转为SolrInputDocument
b.获取solrclient客户端
c.把SolrInputDocument房间solrclient
d.solrclient提交
package com.demo.solr; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.HttpSolrClient; import org.apache.solr.common.SolrInputDocument; import com.demo.solr.config.ISolrFields; import com.demo.solr.model.Product; public class SolrIndexUtils { private static Logger logger = Logger.getLogger(SolrIndexUtils.class); private final static HttpSolrClient solrClient = SolrClientFactory .getInstance().getSolrClient(); public static void addIndexs( List<Product> records) throws SolrServerException, IOException { int count = 0; Collection<SolrInputDocument> docs = new ArrayList<SolrInputDocument>(); int size = records.size(); for (int i = 0; i < size; i++) { SolrInputDocument item = new SolrInputDocument(); Product record = records.get(i); logger.info("Start adding solr index for " + record.toString()); item.addField(ISolrFields.ID, record.getId()); item.addField(ISolrFields.DESCRIPTION,record.getDescription()); item.addField(ISolrFields.KEYWORDS,record.getKeywords()); item.addField(ISolrFields.NAME,record.getName()); item.addField(ISolrFields.SN,record.getSn()); docs.add(item); count++; if (count % 50 == 0 || count == size) { logger.info("Begin commit " + count + " records"); solrClient.add(docs); solrClient.commit(); docs.clear(); logger.info("End commit " + count + " records"); } } } }
7,查询索引
solr查询主要依赖SolrQuery,可以通过setQuery设置查询参数,也可以分页和排序
这里只做一个简单的查询示例
package com.demo.solr; import java.io.IOException; import java.util.List; import org.apache.commons.lang3.StringUtils; 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.QueryResponse; import com.demo.solr.model.Product; public class SolrQueryUtils { private final static HttpSolrClient solrClient = SolrClientFactory .getInstance().getSolrClient(); public static List<Product> search(String name, String keywords, String description, String sn, int start, int limit) throws SolrServerException, IOException{ String searchParam = ""; if (StringUtils.isNotEmpty(name)) { if (StringUtils.isNotEmpty(searchParam)) { searchParam += " AND name:" + name; } else { searchParam += " name:" + name; } } if (StringUtils.isNotEmpty(keywords)) { if (StringUtils.isNotEmpty(searchParam)) { searchParam += " AND keywords:" + keywords; } else { searchParam += " keywords:" + keywords; } } if (StringUtils.isNotEmpty(description)) { if (StringUtils.isNotEmpty(searchParam)) { searchParam += " AND description:" + description; } else { searchParam += " description:" + description; } } if (StringUtils.isNotEmpty(sn)) { if (StringUtils.isNotEmpty(searchParam)) { searchParam += " AND sn:" + sn; } else { searchParam += " sn:" + sn; } } if (!StringUtils.isNotEmpty(searchParam)) { searchParam = "*:*"; } SolrQuery sQuery = new SolrQuery(); sQuery.setQuery(searchParam); sQuery.setStart(start); sQuery.setRows(limit); sQuery.addSort("sn", ORDER.desc); QueryResponse qrsp = solrClient.query(sQuery); List<Product> products = qrsp.getBeans(Product.class); return products; } }
8,我的测试方法
package com.demo.solr; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Random; import java.util.UUID; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.solr.client.solrj.SolrServerException; import com.demo.solr.model.Product; public class Startup { public static void main(String[] args) throws IOException, ParseException, SolrServerException { System.out.println(new Date()); testSearch(); System.out.println(new Date()); } public static void testInsert() throws IOException, SolrServerException{ List<Product> products =new ArrayList<Product>(); Random ran = new Random(); File dataFile=new File("E://data.txt"); FileWriter fileWriter=new FileWriter(dataFile); BufferedWriter bw=new BufferedWriter(fileWriter); for(int i=0;i<100;i++){ String id=UUID.randomUUID().toString(); String name="test"+i+ran.nextInt(5000); String sn="sn-"+333; String keywords="just test-"+UUID.randomUUID().toString().replace("-", ""); products.add(new Product(id, name, keywords, null, sn)); bw.write(id); bw.write("\t"); bw.write(name); bw.write("\t"); bw.write(keywords); bw.write("\t"); bw.write(sn); bw.newLine(); } fileWriter.flush(); bw.close(); fileWriter.close(); System.out.println(products.size()); SolrIndexUtils.addIndexs(products); } public static void testSearch() throws SolrServerException, IOException{ List<Product> search = SolrQueryUtils.search("test2833", null, null, null, 0, 20); for (Product product : search) { System.out.println(product.getId()+"||||||"+product.getName()); } } }
你也可以通过这里查看wiki上的实例,不过貌似是老版本了通过SolrServer创建客户端的方式在新版本中已经不推荐,而使用改为SolrClient了