예제 #1
0
  /**
   * Decorates the given query request with attributes required for geo spatial querying.
   *
   * @param queryRequest the request that needs to be decorated with geo attributes
   * @param latitude the latitude of the item that is being queried
   * @param longitude the longitude of the item that is being queried
   * @param config the configuration to be used for decorating the request with geo attributes
   * @param compositeKeyValue the value of the column that is used in the construction of the
   *     composite hash key(geoHashKey + someOtherColumnValue). This is needed when constructing
   *     queries that need a composite hash key. For eg. Fetch an item where lat/long is 23.78787,
   *     -70.6767 AND category = 'restaurants'
   * @return the decorated request
   */
  public QueryRequest getItemQuery(
      QueryRequest queryRequest,
      double latitude,
      double longitude,
      GeoConfig config,
      Optional<String> compositeKeyValue) {
    checkConfigParams(
        config.getGeoIndexName(),
        config.getGeoHashKeyColumn(),
        config.getGeoHashColumn(),
        config.getGeoHashKeyLength());

    // Generate the geohash and geoHashKey to query by global secondary index
    long geohash = s2Manager.generateGeohash(latitude, longitude);
    long geoHashKey = s2Manager.generateHashKey(geohash, config.getGeoHashKeyLength());
    queryRequest.withIndexName(config.getGeoIndexName());
    Map<String, Condition> keyConditions = new HashMap<String, Condition>();

    // Construct the hashKey condition
    Condition geoHashKeyCondition;
    if (config.getHashKeyDecorator().isPresent() && compositeKeyValue.isPresent()) {
      String hashKey =
          config.getHashKeyDecorator().get().decorate(compositeKeyValue.get(), geoHashKey);
      geoHashKeyCondition =
          new Condition()
              .withComparisonOperator(ComparisonOperator.EQ)
              .withAttributeValueList(new AttributeValue().withS(hashKey));
    } else {
      geoHashKeyCondition =
          new Condition()
              .withComparisonOperator(ComparisonOperator.EQ)
              .withAttributeValueList(new AttributeValue().withN(String.valueOf(geoHashKey)));
    }
    keyConditions.put(config.getGeoHashKeyColumn(), geoHashKeyCondition);

    // Construct the geohash condition
    Condition geoHashCondition =
        new Condition()
            .withComparisonOperator(ComparisonOperator.EQ)
            .withAttributeValueList(new AttributeValue().withN(String.valueOf(geohash)));
    keyConditions.put(config.getGeoHashColumn(), geoHashCondition);

    queryRequest.setKeyConditions(keyConditions);
    return queryRequest;
  }
예제 #2
0
 /**
  * Creates a wrapper that contains a collection of all queries that are generated as a result of
  * this rectangle query. It also contains a filter {@link
  * com.amazonaws.geo.model.filters.GeoFilter} that needs to be applied to the results of the query
  * to ensure that everything is in the bounding box of the queried rectangle. This is needed
  * because queries are fired for every cell that intersects with the rectangle's bounding box.
  *
  * @param queryRequest the request that needs to be decorated with geo attributes
  * @param minLatitude the latitude of the min point of the rectangle
  * @param minLongitude the longitude of the min point of the rectangle
  * @param maxLatitude the latitude of the max point of the rectangle
  * @param maxLongitude the longitude of the max point of the rectangle
  * @param config the configuration to be used for decorating the request with geo attributes
  * @param compositeKeyValue the value of the column that is used in the construction of the
  *     composite hash key(geoHashKey + someOtherColumnValue). This is needed when constructing
  *     queries that need a composite hash key. For eg. Fetch an item where lat/long is 23.78787,
  *     -70.6767 AND category = 'restaurants'
  * @return the wrapper containing the generated queries and the geo filter
  */
 public GeoQueryRequest rectangleQuery(
     QueryRequest queryRequest,
     double minLatitude,
     double minLongitude,
     double maxLatitude,
     double maxLongitude,
     GeoConfig config,
     Optional<String> compositeKeyValue) {
   checkConfigParams(
       config.getGeoIndexName(),
       config.getGeoHashKeyColumn(),
       config.getGeoHashColumn(),
       config.getGeoHashKeyLength());
   // bounding box is needed for the filter and to generate the queries
   // for each cell that intersects with the bounding box
   S2LatLngRect boundingBox =
       s2Manager.getBoundingBoxForRectangleQuery(
           minLatitude, minLongitude, maxLatitude, maxLongitude);
   GeoFilter filter = GeoFilters.newRectangleFilter(boundingBox);
   List<QueryRequest> geoQueries =
       geoQueryHelper.generateGeoQueries(queryRequest, boundingBox, config, compositeKeyValue);
   return new GeoQueryRequest(geoQueries, filter);
 }
예제 #3
0
 /**
  * Creates a wrapper that contains a collection of all queries that are generated as a result of
  * the radius query. It also contains a filter {@link com.amazonaws.geo.model.filters.GeoFilter}
  * that needs to be applied to the results of the query to ensure that everything is in the
  * radius. This is needed because queries are fired for every cell that intersects with the
  * radius' rectangle box.
  *
  * @param queryRequest the request that needs to be decorated with geo attributes
  * @param latitude the latitude of the center point for the radius query
  * @param longitude the longitude of the center point for the radius query
  * @param radius the radius (in metres)
  * @param config the configuration to be used for decorating the request with geo attributes
  * @param compositeKeyValue the value of the column that is used in the construction of the
  *     composite hash key(geoHashKey + someOtherColumnValue). This is needed when constructing
  *     queries that need a composite hash key. For eg. Fetch an item where lat/long is 23.78787,
  *     -70.6767 AND category = 'restaurants'
  * @return the wrapper containing the generated queries and the geo filter
  */
 public GeoQueryRequest radiusQuery(
     QueryRequest queryRequest,
     double latitude,
     double longitude,
     double radius,
     GeoConfig config,
     Optional<String> compositeKeyValue) {
   checkArgument(radius >= 0.0d, "radius has to be a positive value: %s", radius);
   checkConfigParams(
       config.getGeoIndexName(),
       config.getGeoHashKeyColumn(),
       config.getGeoHashColumn(),
       config.getGeoHashKeyLength());
   // Center latLong is needed for the radius filter
   S2LatLng centerLatLng = S2LatLng.fromDegrees(latitude, longitude);
   GeoFilter filter = GeoFilters.newRadiusFilter(centerLatLng, radius);
   // Bounding box is needed to generate queries for each cell that intersects with the bounding
   // box
   S2LatLngRect boundingBox = s2Manager.getBoundingBoxForRadiusQuery(latitude, longitude, radius);
   List<QueryRequest> geoQueries =
       geoQueryHelper.generateGeoQueries(queryRequest, boundingBox, config, compositeKeyValue);
   return new GeoQueryRequest(geoQueries, filter);
 }
예제 #4
0
  /**
   * Decorates the given <code>updateItemRequest</code> with attributes required for geo spatial
   * querying.
   *
   * @param attributeValueMap the items that needs to be decorated with geo attributes
   * @param latitude the latitude that needs to be attached with the item
   * @param longitude the longitude that needs to be attached with the item
   * @param configs the collection of configurations to be used for decorating the request with geo
   *     attributes
   */
  public void updateAttributeValues(
      Map<String, AttributeValue> attributeValueMap,
      double latitude,
      double longitude,
      List<GeoConfig> configs) {
    if (configs == null) {
      throw new IllegalArgumentException("Geo configs should not be null");
    }
    for (GeoConfig config : configs) {
      // Fail-fast if any of the preconditions fail
      checkConfigParams(
          config.getGeoIndexName(),
          config.getGeoHashKeyColumn(),
          config.getGeoHashColumn(),
          config.getGeoHashKeyLength());

      long geohash = s2Manager.generateGeohash(latitude, longitude);
      long geoHashKey = s2Manager.generateHashKey(geohash, config.getGeoHashKeyLength());

      // Decorate the request with the geohash
      AttributeValue geoHashValue = new AttributeValue().withN(Long.toString(geohash));
      attributeValueMap.put(config.getGeoHashColumn(), geoHashValue);

      AttributeValue geoHashKeyValue;
      if (config.getHashKeyDecorator().isPresent()
          && config.getCompositeHashKeyColumn().isPresent()) {
        AttributeValue compositeHashKeyValue =
            attributeValueMap.get(config.getCompositeHashKeyColumn().get());
        if (compositeHashKeyValue == null) {
          continue;
        }
        String compositeColumnValue = compositeHashKeyValue.getS();
        String hashKey =
            config.getHashKeyDecorator().get().decorate(compositeColumnValue, geoHashKey);
        // Decorate the request with the composite geoHashKey (type String)
        geoHashKeyValue = new AttributeValue().withS(String.valueOf(hashKey));
      } else {
        // Decorate the request with the geoHashKey (type Number)
        geoHashKeyValue = new AttributeValue().withN(String.valueOf(geoHashKey));
      }
      attributeValueMap.put(config.getGeoHashKeyColumn(), geoHashKeyValue);
    }
  }