solrJ的使用:适用于地理信息数据的查询匹配

上一节的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,重新进行全量更新的操作,可看到如下数据的变化:
solrJ的使用:适用于地理信息数据的查询匹配_第1张图片

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();

    }

solrJ的使用:适用于地理信息数据的查询匹配_第2张图片

3.2 删除索引

/**
     * 删除索引
     */
    @Test
    public void deleteIndexDemo() throws SolrServerException, IOException{
        solrService.deleteById("cjj");
        solrService.commit();

    }

solrJ的使用:适用于地理信息数据的查询匹配_第3张图片

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();

    }

solrJ的使用:适用于地理信息数据的查询匹配_第4张图片
3.4 查询索引

/**
     * 根据索引查询
     * @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"));
        }

    }

solrJ的使用:适用于地理信息数据的查询匹配_第5张图片

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"));
        }


    }

solrJ的使用:适用于地理信息数据的查询匹配_第6张图片

这里的查询参数也可更换一种方式:

       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倍左右。

你可能感兴趣的:(solr,GIS相关)