コード例 #1
0
  @Override
  public Query parse() throws ParseException {
    // this will combine the results that are found for each
    // administrative level
    BooleanQuery allQuery = new BooleanQuery();

    // attempt to create a query on city (low level administrative division)
    String city = localParams.get(CITY);
    if (city != null) {
      city = city.toLowerCase();
      SchemaField nameField = req.getSchema().getField(NAME_FIELD);
      FieldType nameFieldType = nameField.getType();
      Query cityQuery = nameFieldType.getFieldQuery(this, nameField, city);
      allQuery.add(cityQuery, Occur.MUST);
    }

    // attempt to create a query on state (mid level administrative division)
    String state = localParams.get(STATE);
    if (state != null) {
      state = state.toLowerCase();
      SchemaField stateField = req.getSchema().getField(STATE_FIELD);
      FieldType stateFieldType = stateField.getType();
      Query stateQuery = stateFieldType.getFieldQuery(this, stateField, state);
      allQuery.add(stateQuery, Occur.MUST);
    }

    // attempt to create a query on city (high level administrative division)
    String country = localParams.get(COUNTRY);
    if (country != null) {
      country = country.toLowerCase();
      SchemaField countryField = req.getSchema().getField(COUNTRY_FIELD);
      FieldType countryFieldType = countryField.getType();
      Query countryQuery = countryFieldType.getFieldQuery(this, countryField, country);
      allQuery.add(countryQuery, Occur.MUST);
    }

    String latitude = null;
    String longitude = null;

    // no location provided, computer user's location via reverse-ip lookup
    if (allQuery.getClauses().length == 0) {
      HttpServletRequest httpreq = req.getHttpServletRequest();
      String ip = httpreq.getRemoteAddr();

      LatLng currLoc = geoTargeter.getCurrentLocation(ip);

      if (currLoc != null) {
        latitude = Double.toString(currLoc.getLat());
        longitude = Double.toString(currLoc.getLng());
      }
    } else {
      SolrIndexSearcher searcher = req.getSearcher();
      Document geocodeDoc = null;

      try {
        Sort s = new Sort(new SortField(POPULATION_FIELD, SortField.LONG, true));
        DocList docs = searcher.getDocList(allQuery, new ArrayList<Query>(), s, 0, 1, 0);

        if (docs == null) return query;

        DocIterator iter = docs.iterator();
        int geocodeDocId = iter.nextDoc();
        geocodeDoc = searcher.doc(geocodeDocId);
      } catch (Exception e) {
        e.printStackTrace();
        return query;
      }
      latitude = geocodeDoc.get("latitude");
      longitude = geocodeDoc.get("longitude");
    }

    // combine the spatial and free-text queries
    BooleanQuery finalQuery = new BooleanQuery();

    // if no location is provided and user's location cannot be determined,
    // do not search location
    if (latitude != null && longitude != null) {
      String distance = localParams.get(DISTANCE);

      try {
        Double.parseDouble(distance);
      } catch (Exception e) {
        distance = SEARCH_RADIUS;
      }

      SpatialFilterQParserPlugin spatialFilter = new SpatialFilterQParserPlugin();
      ModifiableSolrParams spatialParams = new ModifiableSolrParams();
      spatialParams.add(SpatialParams.POINT, latitude + "," + longitude);
      spatialParams.add(SpatialParams.DISTANCE, distance);
      spatialParams.add(CommonParams.FL, LOCATION_FIELD);
      Query spatialQuery =
          spatialFilter.createParser(qstr, spatialParams, spatialParams, req).parse();
      finalQuery.add(spatialQuery, Occur.MUST);
    }

    // get results from default LuceneQParser
    Query defQuery = new LuceneQParserPlugin().createParser(qstr, localParams, params, req).parse();

    finalQuery.add(defQuery, Occur.MUST);

    return finalQuery;
  }