public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter) { if (type != "geo_bounding_box") { return(null); } if (!(toFilter is BooleanQuery booleanQuery)) { return(null); } var queryObj = filter as JObject; var first = queryObj.Properties().First(); var ctx = SpatialContext.Geo; var maxLevels = 11; //results in sub-meter precision for geohash // This can also be constructed from SpatialPrefixTreeFactory SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels); var geoPropertyName = first.Name; var strategy = new RecursivePrefixTreeStrategy(grid, geoPropertyName); var boundingBox = (JObject)first.Value; var topLeftProperty = boundingBox["top_left"] as JObject; var bottomRightProperty = boundingBox["bottom_right"] as JObject; if (topLeftProperty == null || bottomRightProperty == null) { return(null); } var left = topLeftProperty["lon"]; var top = topLeftProperty["lat"]; var bottom = bottomRightProperty["lat"]; var right = bottomRightProperty["lon"]; var rectangle = ctx.MakeRectangle((double)left, (double)right, (double)bottom, (double)top); var args = new SpatialArgs(SpatialOperation.Intersects, rectangle); var spatialQuery = strategy.MakeQuery(args); var valueSource = strategy.MakeRecipDistanceValueSource(rectangle); var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1); booleanQuery.Add(new FunctionQuery(valueSource), Occur.MUST); return(new FilteredQuery(booleanQuery, valueSourceFilter)); }
public FilteredQuery CreateFilteredQuery(ILuceneQueryService builder, LuceneQueryContext context, string type, JToken filter, Query toFilter) { if (type != "geo_distance") { return(null); } if (!(toFilter is BooleanQuery booleanQuery)) { return(null); } var queryObj = filter as JObject; if (queryObj.Properties().Count() != 2) { return(null); } var ctx = SpatialContext.Geo; var maxLevels = 11; //results in sub-meter precision for geohash // This can also be constructed from SpatialPrefixTreeFactory SpatialPrefixTree grid = new GeohashPrefixTree(ctx, maxLevels); JProperty distanceProperty = null; JProperty geoProperty = null; foreach (var jProperty in queryObj.Properties()) { if (jProperty.Name.Equals("distance", StringComparison.Ordinal)) { distanceProperty = jProperty; } else { geoProperty = jProperty; } } if (distanceProperty == null || geoProperty == null) { return(null); } var strategy = new RecursivePrefixTreeStrategy(grid, geoProperty.Name); if (!TryParseDistance((string)distanceProperty.Value, out var distanceDegrees)) { return(null); } if (!TryGetPointFromJToken(geoProperty.Value, out var point)) { return(null); } var circle = ctx.MakeCircle(point.X, point.Y, distanceDegrees); var args = new SpatialArgs(SpatialOperation.Intersects, circle); var spatialQuery = strategy.MakeQuery(args); var valueSource = strategy.MakeRecipDistanceValueSource(circle); var valueSourceFilter = new ValueSourceFilter(new QueryWrapperFilter(spatialQuery), valueSource, 0, 1); booleanQuery.Add(new FunctionQuery(valueSource), Occur.MUST); return(new FilteredQuery(booleanQuery, valueSourceFilter)); }