solr空间搜索实现附近酒店的搜索

现在移动开发中越来越多的App都有周边搜索,有找附近的人的,附近的酒店,附近的餐馆的。接下来我们就来讲一下强大的Solr来帮我们构建周边搜索之酒店搜索。

1 下载 Solr 3.6.2

   下载地址:http://www.apache.org/dyn/closer.cgi/lucene/solr/3.6.2

    提取apache-solr-3.6.2.zip里的apache-solr-3.6.2.war到F:\, 后面会讲解如何部署这个war包

2 建立solr的索引库配置

   2.1 在D:\建立目录hotel_solr

   2.2 在D:\hotel_solr下新建solr.xml,内容如下:

Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <solrpersistent="false"> 
  3.   <coresadminPath="/admin/cores"> 
  4.     <corename="core0"instanceDir="core0"/> 
  5.     <!--<core name="core1" instanceDir="core1" />--> 
  6.   </cores> 
  7. </solr> 
   2.3 在D:\hotel_solr新建core0\conf目录

   2.4 在D:\hotel_solr\core0\conf目录下,新建schema.xml文件,内容如下:

Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"?> 
  2. <schemaname="example core zero"version="1.1"> 
  3.   <types> 
  4.    <fieldTypename="string"class="solr.StrField"sortMissingLast="true"omitNorms="true"/> 
  5.          <fieldTypename="boolean"class="solr.BoolField"sortMissingLast="true"omitNorms="true"/> 
  6.          <fieldTypename="integer"class="solr.IntField"omitNorms="true"/> 
  7.          <fieldTypename="int"class="solr.TrieIntField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/> 
  8.          <fieldTypename="float"class="solr.TrieFloatField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/> 
  9.          <fieldTypename="long"class="solr.TrieLongField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/> 
  10.          <fieldTypename="double"class="solr.TrieDoubleField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/> 
  11.          <fieldTypename="tint"class="solr.TrieIntField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/> 
  12.          <fieldTypename="tfloat"class="solr.TrieFloatField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/> 
  13.          <fieldTypename="tlong"class="solr.TrieLongField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/> 
  14.          <fieldTypename="tdouble"class="solr.TrieDoubleField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/> 
  15.          <fieldTypename="sint"class="solr.SortableIntField"sortMissingLast="true"omitNorms="true"/> 
  16.          <fieldTypename="slong"class="solr.SortableLongField"sortMissingLast="true"omitNorms="true"/> 
  17.          <fieldTypename="sfloat"class="solr.SortableFloatField"sortMissingLast="true"omitNorms="true"/> 
  18.          <fieldTypename="sdouble"class="solr.SortableDoubleField"sortMissingLast="true"omitNorms="true"/> 
  19.          <fieldTypename="date"class="solr.TrieDateField"omitNorms="true"precisionStep="0"positionIncrementGap="0"/> 
  20.          <fieldTypename="tdate"class="solr.TrieDateField"omitNorms="true"precisionStep="6"positionIncrementGap="0"/> 
  21.          <fieldtypename="ignored"stored="false"indexed="false"class="solr.StrField"/> 
  22.          <fieldtypename="location"class="solr.LatLonType"subFieldSuffix="_d"/> 
  23.          <fieldTypename="text"class="solr.TextField"positionIncrementGap="100"> 
  24.                <analyzertype="index"> 
  25.                  <tokenizerclass="solr.StandardTokenizerFactory"/> 
  26.                  <filterclass="solr.LowerCaseFilterFactory"/> 
  27.                </analyzer> 
  28.                <analyzertype="query"> 
  29.                  <tokenizerclass="solr.StandardTokenizerFactory"/> 
  30.                  <filterclass="solr.LowerCaseFilterFactory"/> 
  31.                </analyzer> 
  32.          </fieldType> 
  33.   </types> 
  34. <fields> 
  35.   <fieldname="hotel_id"type="integer"indexed="true"stored="true"required="true"/> 
  36.   <fieldname="crawl_hotel_id"   type="string"  indexed="true" stored="true" multiValued="false"required="true"/>   
  37.   <fieldname="name"   type="text"  indexed="true" stored="true" multiValued="false"required="true"/>   
  38.   <fieldname="address"   type="text"  indexed="true" stored="true" multiValued="false"required="true"/>   
  39.   <fieldname="search_kw"type="text"indexed="true"multiValued="true"stored="false"/>   
  40.   <fieldname="latlng"type="location"indexed="true"/> 
  41.   <dynamicFieldname="*_d"type="double"indexed="true"stored="true"/> 
  42. </fields> 
  43. <copyFieldsource="name"dest="search_kw"/> 
  44. <copyFieldsource="address"dest="search_kw"/> 
  45. <uniqueKey>hotel_id</uniqueKey> 
  46. <defaultSearchField>search_kw</defaultSearchField> 
  47. <solrQueryParserdefaultOperator="AND"/> 
  48. </schema> 
    2.5 在D:\hotel_solr\core0\conf目录下,新建solrconfig.xml文件,内容如下:
Xml代码 复制代码 收藏代码
  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <config> 
  3.   <luceneMatchVersion>LUCENE_36</luceneMatchVersion> 
  4.   <directoryFactoryname="DirectoryFactory"class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/> 
  5.   <updateHandlerclass="solr.DirectUpdateHandler2"/> 
  6.   <requestDispatcherhandleSelect="true"> 
  7.     <requestParsersenableRemoteStreaming="false"multipartUploadLimitInKB="2048"/> 
  8.   </requestDispatcher> 
  9.   <requestHandlername="standard"class="solr.StandardRequestHandler"default="true"/> 
  10.   <requestHandlername="/update"class="solr.XmlUpdateRequestHandler"/> 
  11.   <requestHandlername="/admin/"class="org.apache.solr.handler.admin.AdminHandlers"/> 
  12.   <admin> 
  13.     <defaultQuery>*:*</defaultQuery> 
  14.   </admin> 
  15. </config> 
    到这里为止Solr的索引配置完成.

3 配置tomcat

   3.1 让tomcat支持HTTP GET UTF-8编码的支持, 打开D:\apache-tomcat-7.0.16\conf\server.xml,修成如下地方:

Xml代码 复制代码 收藏代码
  1. <Connectorport="8080"protocol="HTTP/1.1"   
  2.                connectionTimeout="20000"   
  3.                redirectPort="8443"URIEncoding="UTF-8"/> 
   3.2 配置solr的war包

         在D:\apache-tomcat-7.0.16\conf\Catalina\localhost新建solr.xml,内容如下:

Xml代码 复制代码 收藏代码
  1. <ContextdocBase="F:/apache-solr-3.6.2.war"debug="0"crossContext="true">    
  2.   <Environmentname="solr/home"type="java.lang.String"value="D:/hotel_solr"override="true"/>    
  3. </Context> 
   3.3 启动tomcat, 在浏览器中输入: http://localhost:8080/solr/   如果出现 Admin core0表示正常。

4 准备酒店数据(如果没有自己去建立)

5 把数据库中的酒店数据添加到Solr索引库中

    使用Solrj客户端进行索引构建和查询,MAVEN依赖包:

Xml代码 复制代码 收藏代码
  1. <dependency> 
  2.       <groupId>junit</groupId> 
  3.       <artifactId>junit</artifactId> 
  4.       <version>3.8.1</version> 
  5.       <scope>test</scope> 
  6.     </dependency> 
  7.     <dependency> 
  8.         <groupId>org.apache.solr</groupId> 
  9.         <artifactId>solr-solrj</artifactId> 
  10.         <version>3.6.0</version> 
  11.     </dependency> 
  12.     <dependency> 
  13.         <groupId>mysql</groupId> 
  14.         <artifactId>mysql-connector-java</artifactId> 
  15.         <version>5.1.19</version> 
  16.     </dependency> 
  17.     <dependency> 
  18.         <groupId>commons-lang</groupId> 
  19.         <artifactId>commons-lang</artifactId> 
  20.         <version>2.6</version> 
  21.     </dependency> 
  22.     <dependency> 
  23.         <groupId>org.apache.httpcomponents</groupId> 
  24.         <artifactId>httpclient</artifactId> 
  25.         <version>4.1.3</version> 
  26.     </dependency> 
  27.     <dependency> 
  28.         <groupId>org.apache.httpcomponents</groupId> 
  29.         <artifactId>httpclient-cache</artifactId> 
  30.         <version>4.1.3</version> 
  31.     </dependency> 
  32.     <dependency> 
  33.         <groupId>org.apache.httpcomponents</groupId> 
  34.         <artifactId>httpmime</artifactId> 
  35.         <version>4.1.3</version> 
  36.     </dependency> 
  37.     <dependency> 
  38.         <groupId>org.slf4j</groupId> 
  39.         <artifactId>slf4j-simple</artifactId> 
  40.         <version>1.6.4</version> 
  41.     </dependency> 
Java代码 复制代码 收藏代码
  1. import java.sql.Connection;  
  2. import java.sql.DriverManager;  
  3. import java.sql.ResultSet;  
  4. import java.sql.SQLException;  
  5. import java.sql.Statement;  
  6. import java.util.HashMap;  
  7. import java.util.Map;  
  8.  
  9. import org.apache.commons.lang.StringUtils;  
  10. import org.apache.solr.client.solrj.SolrRequest.METHOD;  
  11. import org.apache.solr.client.solrj.impl.HttpSolrServer;  
  12. import org.apache.solr.client.solrj.response.QueryResponse;  
  13. import org.apache.solr.common.SolrDocumentList;  
  14. import org.apache.solr.common.SolrInputDocument;  
  15. import org.apache.solr.common.params.MapSolrParams;  
  16.  
  17. public class App {  
  18.  
  19.     /**
  20.      * 初始化索引数据
  21.      * @param solrServer
  22.      * @throws Exception
  23.      */ 
  24.     public staticvoid buildIndex(String solrServer)throws Exception {  
  25.         Connection connect = null;  
  26.         Statement statement = null;  
  27.         ResultSet resultSet = null;  
  28.         HttpSolrServer server = null;  
  29.         try {  
  30.             Class.forName("com.mysql.jdbc.Driver");  
  31.             connect = DriverManager  
  32.                     .getConnection("jdbc:mysql://localhost/hotel_analysis?" 
  33.                             + "user=root&password=11111");  
  34.             statement = connect.createStatement();  
  35.             resultSet = statement  
  36.                     .executeQuery("select hotel_id,crawl_hotel_id,hotel_name,hotel_address,hotel_location from crawl_hotel");  
  37.             server = new HttpSolrServer(solrServer);  
  38.  
  39.             int count = 0;  
  40.  
  41.             int eachCommit = 100;  
  42.             //从数据库中获取酒店数据  
  43.             while (resultSet.next()) {  
  44.                 Integer hotel_id = resultSet.getInt(1);  
  45.                 String crawl_hotel_id = resultSet.getString(2);  
  46.                 String hotel_name = resultSet.getString(3);  
  47.                 String hotel_address = resultSet.getString(4);  
  48.                 String hotel_location = resultSet.getString(5);  
  49.                 if (StringUtils.isBlank(hotel_location)) {  
  50.                     continue;  
  51.                 }  
  52.                 count++;  
  53.                 //添加酒店数据到Solr索引中  
  54.                 SolrInputDocument doc = new SolrInputDocument();  
  55.                 doc.addField("hotel_id", hotel_id);  
  56.                 doc.addField("crawl_hotel_id", crawl_hotel_id);  
  57.                 doc.addField("name", hotel_name);  
  58.                 doc.addField("address", hotel_address);  
  59.                 doc.addField("latlng", hotel_location);  
  60.                 server.add(doc);  
  61.                 //100条commit一次  
  62.                 if (count % eachCommit ==0) {  
  63.                     server.commit();  
  64.                     count = 0;  
  65.                 }  
  66.             }  
  67.             if (count > 0) {  
  68.                 server.commit();  
  69.                 count = 0;  
  70.             }  
  71.         } finally {  
  72.             if (null != resultSet) {  
  73.                 try {  
  74.                     resultSet.close();  
  75.                 } catch (SQLException ex) {  
  76.  
  77.                 }  
  78.             }  
  79.             if (null != statement) {  
  80.                 try {  
  81.                     statement.close();  
  82.                 } catch (SQLException ex) {  
  83.  
  84.                 }  
  85.             }  
  86.             if (null != connect) {  
  87.                 try {  
  88.                     connect.close();  
  89.                 } catch (SQLException ex) {  
  90.  
  91.                 }  
  92.             }  
  93.         }  
  94.     }  
  95.     public staticvoid main(String[] args)throws Exception {  
  96.         String URL = "http://localhost:8080/solr/core0";  
  97.         //构建索引到Solr库  
  98.         buildIndex(URL);  
  99.             //索引周边查询  
  100.         //queryTest(URL);  
  101.     }  
  102.     /**
  103.      * 测试索引查询
  104.      * http://localhost:8080/solr/core0/select?q=*%3A*&fq=%7B%21geofilt%7D&pt=31.26552%2C121.460815&sfield=latlng&d=2&sort=geodist%28%29+asc&fl=*%2Cscore&start=0&rows=10
  105.      * @param solrServer
  106.      * @throws Exception
  107.      */ 
  108.     public staticvoid queryTest(String solrServer)throws Exception {  
  109.         HttpSolrServer server = new HttpSolrServer(solrServer);  
  110.         Map<String,String> params = new HashMap<String,String>();   
  111.         params.put("q", "*:*");  
  112.         params.put("fq", "{!geofilt}");//距离过滤函数 
  113.         params.put("pt", "31.26552,121.460815");//当前经纬度 
  114.         params.put("sfield", "latlng");//经纬度的字段 
  115.         params.put("d", "2");//就近2公里的所有酒店  
  116.         params.put("sort", "geodist() asc");//根据距离排序 
  117.         params.put("fl", "*,score");  
  118.         params.put("start", "0");//记录开始位置  
  119.         params.put("rows", "10");//查询的行数  
  120.         QueryResponse resp = server.query(new MapSolrParams(params), METHOD.POST);  
  121.         SolrDocumentList docs = resp.getResults();  
  122.         for(int i=0;i<docs.size();i++){  
  123.             System.out.println(docs.get(i));  
  124.         }  
  125.     }  
 

6 查询展示:

   

查询结果页:



 

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值