当前位置: 代码迷 >> 互联网 >> Solr空间搜寻之周边酒店搜索
  详细解决方案

Solr空间搜寻之周边酒店搜索

热度:3385   发布时间:2013-02-26 00:00:00.0
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 version="1.0" encoding="UTF-8" ?><solr persistent="false">  <cores adminPath="/admin/cores">    <core name="core0" instanceDir="core0" />    <!--<core name="core1" instanceDir="core1" />-->  </cores></solr>
?? 2.3 在D:\hotel_solr新建core0\conf目录

?

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

<?xml version="1.0" ?><schema name="example core zero" version="1.1">  <types>   <fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="integer" class="solr.IntField" omitNorms="true"/>         <fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="long" class="solr.TrieLongField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="tint" class="solr.TrieIntField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" omitNorms="true" positionIncrementGap="0"/>         <fieldType name="sint" class="solr.SortableIntField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="slong" class="solr.SortableLongField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="sfloat" class="solr.SortableFloatField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="sdouble" class="solr.SortableDoubleField" sortMissingLast="true" omitNorms="true"/>         <fieldType name="date" class="solr.TrieDateField" omitNorms="true" precisionStep="0" positionIncrementGap="0"/>         <fieldType name="tdate" class="solr.TrieDateField" omitNorms="true" precisionStep="6" positionIncrementGap="0"/>         <fieldtype name="ignored" stored="false" indexed="false" class="solr.StrField"/>         <fieldtype name="location" class="solr.LatLonType" subFieldSuffix="_d"/>         <fieldType name="text" class="solr.TextField" positionIncrementGap="100">               <analyzer type="index">                 <tokenizer class="solr.StandardTokenizerFactory"/>                 <filter class="solr.LowerCaseFilterFactory"/>               </analyzer>               <analyzer type="query">                 <tokenizer class="solr.StandardTokenizerFactory"/>                 <filter class="solr.LowerCaseFilterFactory"/>               </analyzer>         </fieldType>  </types> <fields>  <field name="hotel_id" type="integer" indexed="true" stored="true" required="true"/>  <field name="crawl_hotel_id"    type="string"   indexed="true"  stored="true"  multiValued="false" required="true"/>   <field name="name"    type="text"   indexed="true"  stored="true"  multiValued="false" required="true"/>   <field name="address"    type="text"   indexed="true"  stored="true"  multiValued="false" required="true"/>   <field name="search_kw" type="text" indexed="true" multiValued="true" stored="false" />   <field name="latlng" type="location" indexed="true" />  <dynamicField name="*_d" type="double" indexed="true" stored="true"/> </fields> <copyField source="name" dest="search_kw" /> <copyField source="address" dest="search_kw" /> <uniqueKey>hotel_id</uniqueKey> <defaultSearchField>search_kw</defaultSearchField> <solrQueryParser defaultOperator="AND"/></schema>
??? 2.5 在D:\hotel_solr\core0\conf目录下,新建solrconfig.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?><config>  <luceneMatchVersion>LUCENE_36</luceneMatchVersion>  <directoryFactory name="DirectoryFactory" class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>  <updateHandler class="solr.DirectUpdateHandler2" />  <requestDispatcher handleSelect="true" >    <requestParsers enableRemoteStreaming="false" multipartUploadLimitInKB="2048" />  </requestDispatcher>  <requestHandler name="standard" class="solr.StandardRequestHandler" default="true" />  <requestHandler name="/update" class="solr.XmlUpdateRequestHandler" />  <requestHandler name="/admin/" class="org.apache.solr.handler.admin.AdminHandlers" />  <admin>    <defaultQuery>*:*</defaultQuery>  </admin></config>
??? 到这里为止Solr的索引配置完成.

?

3 配置tomcat

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

<Connector port="8080" protocol="HTTP/1.1"                connectionTimeout="20000"                redirectPort="8443" URIEncoding="UTF-8"/>
?? 3.2 配置solr的war包

?

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

<Context docBase="F:/apache-solr-3.6.2.war" debug="0" crossContext="true" >    <Environment name="solr/home" type="java.lang.String" value="D:/hotel_solr" override="true" />  </Context>
?? 3.3 启动tomcat, 在浏览器中输入:http://localhost:8080/solr/?? 如果出现Admin core0 表示正常。

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

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

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

<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>3.6.0</version>    </dependency>    <dependency>    	<groupId>mysql</groupId>    	<artifactId>mysql-connector-java</artifactId>    	<version>5.1.19</version>    </dependency>    <dependency>    	<groupId>commons-lang</groupId>    	<artifactId>commons-lang</artifactId>    	<version>2.6</version>    </dependency>    <dependency>    	<groupId>org.apache.httpcomponents</groupId>    	<artifactId>httpclient</artifactId>    	<version>4.1.3</version>    </dependency>    <dependency>    	<groupId>org.apache.httpcomponents</groupId>    	<artifactId>httpclient-cache</artifactId>    	<version>4.1.3</version>    </dependency>    <dependency>    	<groupId>org.apache.httpcomponents</groupId>    	<artifactId>httpmime</artifactId>    	<version>4.1.3</version>    </dependency>    <dependency>    	<groupId>org.slf4j</groupId>    	<artifactId>slf4j-simple</artifactId>    	<version>1.6.4</version>    </dependency>
??? Java代码:
import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import java.util.HashMap;import java.util.Map;import org.apache.commons.lang.StringUtils;import org.apache.solr.client.solrj.SolrRequest.METHOD;import org.apache.solr.client.solrj.impl.HttpSolrServer;import org.apache.solr.client.solrj.response.QueryResponse;import org.apache.solr.common.SolrDocumentList;import org.apache.solr.common.SolrInputDocument;import org.apache.solr.common.params.MapSolrParams;public class App {	/**	 * 初始化索引数据	 * @param solrServer	 * @throws Exception	 */	public static void buildIndex(String solrServer) throws Exception {		Connection connect = null;		Statement statement = null;		ResultSet resultSet = null;		HttpSolrServer server = null;		try {			Class.forName("com.mysql.jdbc.Driver");			connect = DriverManager					.getConnection("jdbc:mysql://localhost/hotel_analysis?"							+ "user=root&password=11111");			statement = connect.createStatement();			resultSet = statement					.executeQuery("select hotel_id,crawl_hotel_id,hotel_name,hotel_address,hotel_location from crawl_hotel");			server = new HttpSolrServer(solrServer);			int count = 0;			int eachCommit = 100;			//从数据库中获取酒店数据			while (resultSet.next()) {				Integer hotel_id = resultSet.getInt(1);				String crawl_hotel_id = resultSet.getString(2);				String hotel_name = resultSet.getString(3);				String hotel_address = resultSet.getString(4);				String hotel_location = resultSet.getString(5);				if (StringUtils.isBlank(hotel_location)) {					continue;				}				count++;				//添加酒店数据到Solr索引中				SolrInputDocument doc = new SolrInputDocument();				doc.addField("hotel_id", hotel_id);				doc.addField("crawl_hotel_id", crawl_hotel_id);				doc.addField("name", hotel_name);				doc.addField("address", hotel_address);				doc.addField("latlng", hotel_location);				server.add(doc);				//100条commit一次				if (count % eachCommit == 0) {					server.commit();					count = 0;				}			}			if (count > 0) {				server.commit();				count = 0;			}		} finally {			if (null != resultSet) {				try {					resultSet.close();				} catch (SQLException ex) {				}			}			if (null != statement) {				try {					statement.close();				} catch (SQLException ex) {				}			}			if (null != connect) {				try {					connect.close();				} catch (SQLException ex) {				}			}		}	}	public static void main(String[] args) throws Exception {		String URL = "http://localhost:8080/solr/core0";		//构建索引到Solr库		buildIndex(URL);	        //索引周边查询		//queryTest(URL);	}	/**	 * 测试索引查询	 * 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	 * @param solrServer	 * @throws Exception	 */	public static void queryTest(String solrServer) throws Exception {		HttpSolrServer server = new HttpSolrServer(solrServer);		Map<String,String> params = new HashMap<String,String>(); 		params.put("q", "*:*");		params.put("fq", "{!geofilt}");//距离过滤函数		params.put("pt", "31.26552,121.460815");//当前经纬度		params.put("sfield", "latlng");//经纬度的字段		params.put("d", "2");//就近2公里的所有酒店		params.put("sort", "geodist() asc");//根据距离排序		params.put("fl", "*,score");		params.put("start", "0");//记录开始位置		params.put("rows", "10");//查询的行数		QueryResponse resp = server.query(new MapSolrParams(params), METHOD.POST);		SolrDocumentList docs = resp.getResults();		for(int i=0;i<docs.size();i++){			System.out.println(docs.get(i));		}	}}
?

6 查询展示:

???

?

查询结果页:



?

?
?
  相关解决方案