您的位置:首页 > 其它

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

2015-07-14 16:55 549 查看

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代码








<?xmlversion="1.0"encoding="UTF-8"?>
<solrpersistent="false">
<coresadminPath="/admin/cores">
<corename="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代码








<?xmlversion="1.0"?>
<schemaname="example
core zero"version="1.1">
<types>
<fieldTypename="string"class="solr.StrField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="boolean"class="solr.BoolField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="integer"class="solr.IntField"omitNorms="true"/>
<fieldTypename="int"class="solr.TrieIntField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="float"class="solr.TrieFloatField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="long"class="solr.TrieLongField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="double"class="solr.TrieDoubleField"precisionStep="0"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="tint"class="solr.TrieIntField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="tfloat"class="solr.TrieFloatField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="tlong"class="solr.TrieLongField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="tdouble"class="solr.TrieDoubleField"precisionStep="8"omitNorms="true"positionIncrementGap="0"/>
<fieldTypename="sint"class="solr.SortableIntField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="slong"class="solr.SortableLongField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="sfloat"class="solr.SortableFloatField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="sdouble"class="solr.SortableDoubleField"sortMissingLast="true"omitNorms="true"/>
<fieldTypename="date"class="solr.TrieDateField"omitNorms="true"precisionStep="0"positionIncrementGap="0"/>
<fieldTypename="tdate"class="solr.TrieDateField"omitNorms="true"precisionStep="6"positionIncrementGap="0"/>
<fieldtypename="ignored"stored="false"indexed="false"class="solr.StrField"/>
<fieldtypename="location"class="solr.LatLonType"subFieldSuffix="_d"/>
<fieldTypename="text"class="solr.TextField"positionIncrementGap="100">
<analyzertype="index">
<tokenizerclass="solr.StandardTokenizerFactory"/>
<filterclass="solr.LowerCaseFilterFactory"/>
</analyzer>
<analyzertype="query">
<tokenizerclass="solr.StandardTokenizerFactory"/>
<filterclass="solr.LowerCaseFilterFactory"/>
</analyzer>
</fieldType>
</types>
<fields>
<fieldname="hotel_id"type="integer"indexed="true"stored="true"required="true"/>
<fieldname="crawl_hotel_id" type="string" indexed="true" stored="true" multiValued="false"required="true"/>
<fieldname="name" type="text" indexed="true" stored="true" multiValued="false"required="true"/>
<fieldname="address" type="text" indexed="true" stored="true" multiValued="false"required="true"/>
<fieldname="search_kw"type="text"indexed="true"multiValued="true"stored="false"/>
<fieldname="latlng"type="location"indexed="true"/>
<dynamicFieldname="*_d"type="double"indexed="true"stored="true"/>
</fields>
<copyFieldsource="name"dest="search_kw"/>
<copyFieldsource="address"dest="search_kw"/>
<uniqueKey>hotel_id</uniqueKey>
<defaultSearchField>search_kw</defaultSearchField>
<solrQueryParserdefaultOperator="AND"/>
</schema>

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

Xml代码








<?xmlversion="1.0"encoding="UTF-8"?>
<config>
<luceneMatchVersion>LUCENE_36</luceneMatchVersion>
<directoryFactoryname="DirectoryFactory"class="${solr.directoryFactory:solr.StandardDirectoryFactory}"/>
<updateHandlerclass="solr.DirectUpdateHandler2"/>
<requestDispatcherhandleSelect="true">
<requestParsersenableRemoteStreaming="false"multipartUploadLimitInKB="2048"/>
</requestDispatcher>
<requestHandlername="standard"class="solr.StandardRequestHandler"default="true"/>
<requestHandlername="/update"class="solr.XmlUpdateRequestHandler"/>
<requestHandlername="/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,修成如下地方:

Xml代码








<Connectorport="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,内容如下:

Xml代码








<ContextdocBase="F:/apache-solr-3.6.2.war"debug="0"crossContext="true">
<Environmentname="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客户端进行索引构建和查询,M***EN依赖包:

Xml代码








<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 staticvoid 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 staticvoid 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 staticvoid 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 查询展示:





查询结果页:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: