上一节的dataimport 我们是直接导入的字符串类型的数据,为了配合本次solrJ的使用详解,结合实际例子,我们更改如下配置:
1、data-config.xml的配置:讲营业部id ,名称和经纬度数据放在solr服务器上。这里要注意的一点是location_point字段,这个是我们自定义的,对应的数据是纬度,经度的表达式。
<dataConfig>
<dataSource driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@192.168.17.184:1521:gisdev" user="gisdev" password="gisdev"/> <document name="salesDoc">
<entity name="t_map_point" query="select id ,name ,(lat_baidu||','||lng_baidu) as location_point from t_map_point where type ='SALES_DEPT' and isvalid ='1' " >
<field name="id" column="id" />
<field name="name" column="name" />
<field name="location_point" column="location_point" />
entity>
document>
dataConfig>
2、那solr 如何识别location_point为地理信息数据呢?
在schema.xml中定义该字段(我们要放在solr上的自定义字段都需要该文件中声明):指向location_rpt类型
<field name="location_point" type="location_rpt" indexed="true" stored="true" multiValued="false"/>
<fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
geo="true" distErrPct="0.025" maxDistErr="0.000009" units="degrees" />
重启solr,重新进行全量更新的操作,可看到如下数据的变化:
3、solrJ对索引的操作:底层是封装了httpClient请求,对外API提供了SolrServer的几个实现类。我们这里着重介绍HttpSolrServer。
要想使用HttpSolrServer,首先还是得加jar包,由于我这里是maven工程的,我直接在pom.xml中添加对solrJ的依赖即可:
<dependency>
<groupId>org.apache.solrgroupId>
<artifactId>solr-coreartifactId>
<version>4.7.0version>
dependency>
实际对应了哪些jar包呢?~自己找去吧~哈哈,网上一堆。
3.1 增加索引:
/**
* 因为solr的服务不是包含在项目内的,而是单独的服务,
* 这里,我们需要有http连接,所以使用HttpSolrServer实例化SolrServer这个抽象类
*/
//实例化一个全局的solrService对象
SolrServer solrService = new HttpSolrServer("http://localhost:8080/solr/collection1");
/**
* 增加索引
* @throws IOException
* @throws SolrServerException
*/
@Test
public void addIndexDemo() throws SolrServerException, IOException{
SolrInputDocument sid = new SolrInputDocument();
sid.setField("id","cjj");
sid.setField("location_point","19.263661889321,110.45638934559");
sid.setField("name","增加索引");
solrService.add(sid);
solrService.commit();
}
3.2 删除索引
/**
* 删除索引
*/
@Test
public void deleteIndexDemo() throws SolrServerException, IOException{
solrService.deleteById("cjj");
solrService.commit();
}
3.3 修改索引
/**
* 修改索引
*/
@Test
public void updateIndexDemo() throws SolrServerException, IOException{
SolrInputDocument sid = new SolrInputDocument();
sid.setField("id","cjj");
sid.setField("location_point","20.263661889321,100.45638934559");
sid.setField("name","修改索引");
solrService.add(sid);
solrService.commit();
}
/**
* 根据索引查询
* @throws SolrServerException
*/
@Test
public void testQuery() throws SolrServerException{
SolrQuery query = new SolrQuery();
query.setQuery("id:DC5AA2B0BDF8F26FE0433665A8C0A047");
QueryResponse solrRsp = solrService.query(query);
SolrDocumentList citySolrList = solrRsp.getResults();
for(SolrDocument docc : citySolrList){
System.out.println(docc.getFieldValue("id"));
System.out.println(docc.getFieldValue("name"));
System.out.println(docc.getFieldValue("location_point"));
}
}
4 根据客户坐标搜索100公里内的营业部的demo
/**
* 根据客户坐标搜索100公里内的营业部:
* @throws SolrServerException
*/
@Test
public void matchDepts() throws SolrServerException{
String point = "31.177745,121.15081";//客户坐标
SolrQuery query = new SolrQuery();
query.set("q", "*:*");//距离过滤函数
query.set("fq", "{!geofilt}");//距离过滤函数
query.set("pt", point);//当前经纬度
query.set("sfield", "location_point");//经纬度的字段
query.set("d", "1000");//搜索100公里内的营业部
query.set("sort", "geodist() asc");//根据距离排序
query.set("fl", "*,geodist()"); //搜索结果返回字段
query.set("start", "0");//记录开始位置
query.set("rows", "5");//查询的行数
QueryResponse solrRsp = solrService.query(query);
SolrDocumentList citySolrList = solrRsp.getResults();
System.out.println(citySolrList.size());
for(SolrDocument docc : citySolrList){
System.out.println(docc.getFieldValue("id"));
System.out.println(docc.getFieldValue("name"));
System.out.println(docc.getFieldValue("location_point"));
}
}
这里的查询参数也可更换一种方式:
String point = "31.177745,121.15081";//客户坐标
Map<String,String> params = new HashMap<String,String>();
params.put("q", "*:*");
params.put("fq", "{!geofilt}");//距离过滤函数
params.put("pt", point);//当前经纬度
params.put("sfield", "location_point");//经纬度的字段
params.put("d", "100");//搜索100公里内的营业部
params.put("sort", "geodist() asc");//根据距离排序
params.put("fl", "*,geodist()"); //搜索结果返回字段
params.put("start", "0");//记录开始位置
params.put("rows", "5");//查询的行数
QueryResponse solrRsp = solrService.query(new MapSolrParams(params));
SolrDocumentList citySolrList = solrRsp.getResults();
System.out.println(citySolrList.size());
for(SolrDocument docc : citySolrList){
System.out.println(docc.getFieldValue("id"));
System.out.println(docc.getFieldValue("name"));
System.out.println(docc.getFieldValue("location_point"));
}
在企业应用中,通常我们只需要第一次全量导入数据,而后通过MQ对solr进行增量索引修改,这些数据既可以做地理信息业务相关的匹配,也可以做文本数据的联想搜索,查询速度相当快,Oracle Spatial的空间查询在点到点的匹配上完全比不上solr的查询。solr的空间索引查询速度较Oracle Spatial的空间查询快46倍左右。