package org.opensextant.matching;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.opensextant.placedata.Geocoord;
import org.opensextant.placedata.Place;
import org.opensextant.placedata.ScoredPlace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PlacenameSearcher {
private SolrClient solrServer;
private ModifiableSolrParams baseSearchParams = new ModifiableSolrParams();
/** Log object. */
private static final Logger LOGGER = LoggerFactory.getLogger(PlacenameSearcher.class);
protected PlacenameSearcher(SolrClient svr, ModifiableSolrParams prms) {
solrServer = svr;
baseSearchParams = new ModifiableSolrParams(prms);
}
private List<Place> search(ModifiableSolrParams prms) {
List<Place> places = new ArrayList<Place>();
QueryResponse response = null;
try {
response = solrServer.query(prms);
} catch (SolrServerException | IOException e) {
LOGGER.error("Got exception when processing query.", e);
return places;
}
if (response != null) {
SolrDocumentList docList = response.getResults();
for (SolrDocument d : docList) {
Place p = MatcherFactory.createPlace(d);
places.add(p);
}
}
return places;
}
public SolrDocumentList dumpDocs(String q) {
ModifiableSolrParams srchParams = new ModifiableSolrParams(baseSearchParams);
srchParams.set("q", q);
QueryResponse response = null;
try {
response = solrServer.query(srchParams);
} catch (SolrServerException | IOException e) {
LOGGER.error("Got exception when processing query.", e);
return null;
}
if (response != null) {
return response.getResults();
}
return null;
}
public List<Place> searchByQueryString(String query) {
ModifiableSolrParams srchParams = new ModifiableSolrParams(baseSearchParams);
srchParams.set("q", query);
return search(srchParams);
}
public List<Place> searchByPlaceName(String placeName, boolean fuzzy) {
ModifiableSolrParams srchParams = new ModifiableSolrParams(baseSearchParams);
String query = "name:";
if (fuzzy) {
query = query + placeName + "~0.80";
} else {
query = query + "\"" + placeName + "\"";
}
srchParams.set("defType", "edismax");
srchParams.set("q", query);
return search(srchParams);
}
/** Distance in kilometers. */
public List<ScoredPlace> searchByCircle(Geocoord center, double distance) {
return searchByCircle(center.getLatitude(), center.getLongitude(), distance);
}
/** Distance in kilometers. */
public List<ScoredPlace> searchByCircle(double lat, double lon, double distance) {
ModifiableSolrParams srchParams = new ModifiableSolrParams(baseSearchParams);
String query = "{!geofilt pt=" + lat + "," + lon + " sfield=geo" + " d=" + distance + "}";
srchParams.set("q", query);
List<ScoredPlace> places = new ArrayList<ScoredPlace>();
QueryResponse response = null;
try {
response = solrServer.query(srchParams);
} catch (SolrServerException | IOException e) {
LOGGER.error("Got exception when processing query.", e);
return places;
}
if (response != null) {
SolrDocumentList docList = response.getResults();
for (SolrDocument d : docList) {
Place p = MatcherFactory.createPlace(d);
double dist = p.getGeocoord().distance(lat, lon);
places.add(new ScoredPlace(p, dist));
}
}
// sort by distance (ascending)
Collections.sort(places);
Collections.reverse(places);
return places;
}
/**
* TODO add search variants for exact/inexact name, constraints
* (country,feature type), geo radius ...
*/
public void cleanup() {
MatcherFactory.shutdown(this);
}
}