Skip to content

Commit e28e03e

Browse files
committed
Add relation to geo_shape queries
Add Contains to geoshape relations. Forward port of PR #2187
1 parent 51512f6 commit e28e03e

File tree

15 files changed

+54
-9
lines changed

15 files changed

+54
-9
lines changed

src/Nest/CommonAbstractions/Extensions/Extensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ internal static IEnumerable<T> DistinctBy<T, TKey>(this IEnumerable<T> items, Fu
5858
internal static ConcurrentDictionary<string, object> _enumCache = new ConcurrentDictionary<string, object>();
5959
internal static T? ToEnum<T>(this string str, StringComparison comparison = StringComparison.OrdinalIgnoreCase) where T : struct
6060
{
61+
if (str == null) return null;
62+
6163
var enumType = typeof(T);
6264
var key = $"{enumType.Name}.{str}";
6365
object value;

src/Nest/CommonOptions/Geo/GeoShapeRelation.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public enum GeoShapeRelation
1212
[EnumMember(Value = "disjoint")]
1313
Disjoint,
1414
[EnumMember(Value = "within")]
15-
Within
15+
Within,
16+
[EnumMember(Value = "contains")]
17+
Contains
1618
}
1719
}

src/Nest/QueryDsl/Geo/Shape/Circle/GeoShapeCircleQuery.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class GeoShapeCircleQuery : GeoShapeQueryBase, IGeoShapeCircleQuery
1515
public ICircleGeoShape Shape { get; set; }
1616

1717
internal override void InternalWrapInContainer(IQueryContainer c) => c.GeoShape = this;
18+
1819
internal static bool IsConditionless(IGeoShapeCircleQuery q) => q.Field.IsConditionless() || q.Shape == null || q.Shape.Coordinates == null;
1920
}
2021

src/Nest/QueryDsl/Geo/Shape/GeoShapeQueryJsonConverter.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
3636
JToken shape;
3737
JToken indexedShape;
3838
IGeoShapeQuery query = null;
39+
3940
if (jo.TryGetValue("shape", out shape))
4041
query = ParseShape(shape, serializer);
4142
else if (jo.TryGetValue("indexed_shape", out indexedShape))
@@ -44,10 +45,12 @@ public override object ReadJson(JsonReader reader, Type objectType, object exist
4445
if (query == null) return null;
4546
var boost = jo["boost"]?.Value<double>();
4647
var name = jo["_name"]?.Value<string>();
48+
var relation = jo["relation"]?.Value<string>().ToEnum<GeoShapeRelation>();
4749
var ignoreUnmapped = jo["ignore_unmapped"]?.Value<bool>();
4850
query.Boost = boost;
4951
query.Name = name;
5052
query.Field = field;
53+
query.Relation = relation;
5154
query.IgnoreUnmapped = ignoreUnmapped;
5255
return query;
5356
}

src/Nest/QueryDsl/Geo/Shape/IGeoShapeQuery.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@ namespace Nest
66
[JsonConverter(typeof (CompositeJsonConverter<GeoShapeQueryJsonConverter, FieldNameQueryJsonConverter<GeoShapeCircleQuery>>))]
77
public interface IGeoShapeQuery : IFieldNameQuery
88
{
9+
/// <summary>
10+
/// Controls the spatial relation operator to used at search time.
11+
/// </summary>
12+
[JsonProperty("relation")]
13+
GeoShapeRelation? Relation { get; set; }
14+
915
/// <summary>
1016
/// Will ignore an unmapped field and will not match any documents for this query.
1117
/// This can be useful when querying multiple indexes which might have different mappings.
@@ -16,6 +22,11 @@ public interface IGeoShapeQuery : IFieldNameQuery
1622

1723
public abstract class GeoShapeQueryBase : FieldNameQueryBase, IGeoShapeQuery
1824
{
25+
/// <summary>
26+
/// Controls the spatial relation operator to used at search time.
27+
/// </summary>
28+
public GeoShapeRelation? Relation { get; set; }
29+
1930
/// <summary>
2031
/// Will ignore an unmapped field and will not match any documents for this query.
2132
/// This can be useful when querying multiple indexes which might have different mappings.
@@ -30,6 +41,12 @@ public abstract class GeoShapeQueryDescriptorBase<TDescriptor, TInterface, T>
3041
where T : class
3142
{
3243
bool? IGeoShapeQuery.IgnoreUnmapped { get; set; }
44+
GeoShapeRelation? IGeoShapeQuery.Relation { get; set; }
45+
46+
/// <summary>
47+
/// Controls the spatial relation operator to used at search time.
48+
/// </summary>
49+
public TDescriptor Relation(GeoShapeRelation relation) => Assign(a => a.Relation = relation);
3350

3451
/// <summary>
3552
/// Will ignore an unmapped field and will not match any documents for this query.

src/Nest/QueryDsl/Geo/Shape/MultiPolygon/GeoShapeMultiPolygonQuery.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ public class GeoShapeMultiPolygonQueryDescriptor<T>
2828

2929
public GeoShapeMultiPolygonQueryDescriptor<T> Coordinates(IEnumerable<IEnumerable<IEnumerable<GeoCoordinate>>> coordinates) =>
3030
Assign(a => a.Shape = new MultiPolygonGeoShape { Coordinates = coordinates });
31+
32+
3133
}
3234
}

src/Tests/QueryDsl/Geo/Shape/Circle/GeoShapeCircleUsageTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ public GeoShapeCircleUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i
2323
Name = "named_query",
2424
Boost = 1.1,
2525
Field = Field<Project>(p=>p.Location),
26-
IgnoreUnmapped = false,
27-
Shape = new CircleGeoShape(this._coordinates) { Radius = "100m" }
26+
Shape = new CircleGeoShape(this._coordinates) { Radius = "100m" },
27+
Relation = GeoShapeRelation.Intersects,
28+
IgnoreUnmapped = false
2829
};
2930

3031
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
@@ -35,6 +36,7 @@ protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project>
3536
.IgnoreUnmapped()
3637
.Coordinates(this._coordinates)
3738
.Radius("100m")
39+
.Relation(GeoShapeRelation.Intersects)
3840
);
3941

4042
protected override ConditionlessWhen ConditionlessWhen => new ConditionlessWhen<IGeoShapeCircleQuery>(a => a.GeoShape as IGeoShapeCircleQuery)

src/Tests/QueryDsl/Geo/Shape/Envelope/GeoEnvelopeUsageTests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ public GeoEnvelopeUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(i, u
2727
Name = "named_query",
2828
Boost = 1.1,
2929
Field = Field<Project>(p=>p.Location),
30-
IgnoreUnmapped = false,
31-
Shape = new EnvelopeGeoShape(this._coordinates)
30+
Shape = new EnvelopeGeoShape(this._coordinates),
31+
Relation = GeoShapeRelation.Intersects,
32+
IgnoreUnmapped = false
3233
};
3334

3435
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
@@ -38,6 +39,7 @@ protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project>
3839
.Field(p=>p.Location)
3940
.IgnoreUnmapped()
4041
.Coordinates(this._coordinates)
42+
.Relation(GeoShapeRelation.Intersects)
4143
);
4244

4345
protected override ConditionlessWhen ConditionlessWhen => new ConditionlessWhen<IGeoShapeEnvelopeQuery>(a => a.GeoShape as IGeoShapeEnvelopeQuery)

src/Tests/QueryDsl/Geo/Shape/GeoShapeQueryUsageTestsBase.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public GeoShapeQueryUsageTestsBase(ReadOnlyCluster i, EndpointUsage usage) : bas
1717
_name="named_query",
1818
boost = 1.1,
1919
ignore_unmapped = false,
20+
relation = "intersects",
2021
shape = this.ShapeJson
2122
}
2223
}

src/Tests/QueryDsl/Geo/Shape/IndexedShape/GeoIndexedShapeUsageTests.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ public GeoIndexedShapeUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(
1717
{
1818
_name="named_query",
1919
boost = 1.1,
20-
indexed_shape = new
20+
indexed_shape = new
2121
{
2222
id = 2,
2323
type = "project",
2424
index = "project",
2525
path = "location"
26-
}
26+
},
27+
relation = "intersects"
2728
}
2829
}
2930
};
@@ -38,8 +39,9 @@ public GeoIndexedShapeUsageTests(ReadOnlyCluster i, EndpointUsage usage) : base(
3839
Id = 2,
3940
Index = Index<Project>(),
4041
Type = Type<Project>(),
41-
Path = Field<Project>(p=>p.Location)
42-
}
42+
Path = Field<Project>(p=>p.Location),
43+
},
44+
Relation = GeoShapeRelation.Intersects
4345
};
4446

4547
protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project> q) => q
@@ -51,6 +53,7 @@ protected override QueryContainer QueryFluent(QueryContainerDescriptor<Project>
5153
.Id(2)
5254
.Path(pp=>pp.Location)
5355
)
56+
.Relation(GeoShapeRelation.Intersects)
5457
);
5558

5659
protected override ConditionlessWhen ConditionlessWhen => new ConditionlessWhen<IGeoIndexedShapeQuery>(a => a.GeoShape as IGeoIndexedShapeQuery)

0 commit comments

Comments
 (0)