From 396a9b56cfaedca274537d856c09330c5da862f3 Mon Sep 17 00:00:00 2001 From: evanchooly Date: Thu, 13 Jun 2024 00:04:57 -0400 Subject: [PATCH] more tests. geo stuff. --- .../kotlin/dev/morphia/audits/RstAuditor.kt | 2 - .../java/dev/morphia/MorphiaDatastore.java | 2 + .../codec/MorphiaFilterCodecProvider.java | 2 + .../codec/MorphiaTypesCodecProvider.java | 1 + .../codec/PolygonCoordinatesCodec.java | 127 ++++++++++++++++++ .../codec/filters/GeoWithinFilterCodec.java | 62 +++++++++ .../dev/morphia/query/filters/Filter.java | 1 + .../test/query/filters/TestBitsAnyClear.java | 12 ++ .../test/query/filters/TestBitsAnySet.java | 21 ++- .../morphia/test/query/filters/TestBox.java | 23 ++++ .../test/query/filters/TestElemMatch.java | 12 ++ .../morphia/test/query/filters/TestEq.java | 20 +++ .../test/query/filters/TestGeoWithin.java | 56 ++++++++ .../morphia/test/query/filters/TestGt.java | 20 +++ .../test/query/filters/TestPolygon.java | 26 ++++ .../query/filters/box/example1/action.json | 3 + .../test/query/filters/box/example1/lock | 1 + .../test/query/filters/box/example1/name | 1 + .../filters/geoWithin/example1/action.json | 12 ++ .../query/filters/geoWithin/example1/lock | 1 + .../query/filters/geoWithin/example1/name | 1 + .../filters/geoWithin/example2/action.json | 20 +++ .../query/filters/geoWithin/example2/name | 1 + .../query/filters/gt/example1/action.json | 1 + .../test/query/filters/gt/example1/data.json | 3 + .../query/filters/gt/example1/expected.json | 2 + .../test/query/filters/gt/example1/name | 1 + .../filters/polygon/example1/action.json | 7 + .../test/query/filters/polygon/example1/lock | 1 + .../test/query/filters/polygon/example1/name | 1 + 30 files changed, 435 insertions(+), 8 deletions(-) create mode 100644 core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java create mode 100644 core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java create mode 100644 core/src/test/java/dev/morphia/test/query/filters/TestBox.java create mode 100644 core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java create mode 100644 core/src/test/java/dev/morphia/test/query/filters/TestGt.java create mode 100644 core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/box/example1/name create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock create mode 100644 core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name diff --git a/audits/src/main/kotlin/dev/morphia/audits/RstAuditor.kt b/audits/src/main/kotlin/dev/morphia/audits/RstAuditor.kt index 56cfdbbab73..ed5d8f4df81 100644 --- a/audits/src/main/kotlin/dev/morphia/audits/RstAuditor.kt +++ b/audits/src/main/kotlin/dev/morphia/audits/RstAuditor.kt @@ -180,7 +180,6 @@ class RstAuditor(val type: OperatorType) { } source.addTestCases(operator) - println("**************** source = \n\n${source}") if (!outputFile.parentFile.mkdirs() && !outputFile.parentFile.exists()) { throw IOException( String.format("Could not create directory: %s", outputFile.parentFile) @@ -212,7 +211,6 @@ class RstAuditor(val type: OperatorType) { text = "test data: ${example.folder.relativeTo(coreTestRoot)}\n" + text method.javaDoc.text = text } - println("**************** text = ${text}") } private fun updateTestAnnotation( diff --git a/core/src/main/java/dev/morphia/MorphiaDatastore.java b/core/src/main/java/dev/morphia/MorphiaDatastore.java index 8fc3339d97e..7bec27565a0 100644 --- a/core/src/main/java/dev/morphia/MorphiaDatastore.java +++ b/core/src/main/java/dev/morphia/MorphiaDatastore.java @@ -21,6 +21,7 @@ import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.CreateCollectionOptions; import com.mongodb.client.model.ValidationOptions; +import com.mongodb.client.model.geojson.codecs.GeoJsonCodecProvider; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.InsertManyResult; import com.mongodb.client.result.InsertOneResult; @@ -172,6 +173,7 @@ private CodecRegistry buildRegistry(CodecRegistry codecRegistry) { providers.addAll(morphiaCodecProviders); providers.add(codecRegistry); + providers.add(new GeoJsonCodecProvider()); codecRegistry = fromProviders(providers); return codecRegistry; } diff --git a/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java b/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java index a36229d9ee2..1e9c2ea7caf 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java +++ b/core/src/main/java/dev/morphia/mapping/codec/MorphiaFilterCodecProvider.java @@ -14,6 +14,7 @@ import dev.morphia.mapping.codec.filters.FieldLessFilterCodec; import dev.morphia.mapping.codec.filters.FilterCodec; import dev.morphia.mapping.codec.filters.GeoIntersectsFilterCodec; +import dev.morphia.mapping.codec.filters.GeoWithinFilterCodec; import dev.morphia.mapping.codec.filters.JsonSchemaFilterCodec; import dev.morphia.mapping.codec.filters.LogicalFilterCodec; import dev.morphia.mapping.codec.filters.NearFilterCodec; @@ -43,6 +44,7 @@ public MorphiaFilterCodecProvider(MorphiaDatastore datastore) { addCodec(new FilterCodec(datastore)); addCodec(new FieldLessFilterCodec(datastore)); addCodec(new GeoIntersectsFilterCodec(datastore)); + addCodec(new GeoWithinFilterCodec(datastore)); addCodec(new JsonSchemaFilterCodec(datastore)); addCodec(new LogicalFilterCodec(datastore)); addCodec(new ModFilterCodec(datastore)); diff --git a/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java b/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java index 8516609a6f5..55bd23f281c 100644 --- a/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java +++ b/core/src/main/java/dev/morphia/mapping/codec/MorphiaTypesCodecProvider.java @@ -30,6 +30,7 @@ public MorphiaTypesCodecProvider(MorphiaDatastore datastore) { addCodec(new MorphiaMapCodec(datastore)); addCodec(new MorphiaLocalDateTimeCodec(datastore)); addCodec(new MorphiaLocalTimeCodec()); + addCodec(new PolygonCoordinatesCodec()); addCodec(new ClassCodec()); addCodec(new LocaleCodec()); addCodec(new ObjectCodec(datastore)); diff --git a/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java b/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java new file mode 100644 index 00000000000..2ff331e7d34 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/PolygonCoordinatesCodec.java @@ -0,0 +1,127 @@ +package dev.morphia.mapping.codec; + +import java.util.ArrayList; +import java.util.List; + +import com.mongodb.client.model.geojson.PolygonCoordinates; +import com.mongodb.client.model.geojson.Position; + +import org.bson.BsonReader; +import org.bson.BsonType; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.codecs.configuration.CodecConfigurationException; + +import static java.lang.String.format; + +/** + * This codec has been cobbled together via sources from com.mongodb.client.model.geojson.codecs.GeometryDecoderHelper + * and com.mongodb.client.model.geojson.codecs.GeometryEncoderHelper + */ +public class PolygonCoordinatesCodec implements Codec { + + @Override + public PolygonCoordinates decode(BsonReader reader, DecoderContext decoderContext) { + reader.readStartArray(); + List> values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(decodeCoordinates(reader)); + } + reader.readEndArray(); + + if (values.isEmpty()) { + throw new CodecConfigurationException("Invalid Polygon no coordinates."); + } + + List exterior = values.remove(0); + + try { + return new PolygonCoordinates(exterior, values); + } catch (IllegalArgumentException e) { + throw new CodecConfigurationException(format("Invalid Polygon: %s", e.getMessage())); + } + + } + + @Override + public void encode(BsonWriter writer, PolygonCoordinates polygonCoordinates, EncoderContext encoderContext) { + writer.writeStartArray(); + encodeLinearRing(polygonCoordinates.getExterior(), writer); + for (List ring : polygonCoordinates.getHoles()) { + encodeLinearRing(ring, writer); + } + writer.writeEndArray(); + } + + @Override + public Class getEncoderClass() { + return PolygonCoordinates.class; + } + + private static List decodeCoordinates(final BsonReader reader) { + validateIsArray(reader); + reader.readStartArray(); + List values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(decodePosition(reader)); + } + reader.readEndArray(); + return values; + } + + private static Position decodePosition(final BsonReader reader) { + validateIsArray(reader); + reader.readStartArray(); + List values = new ArrayList<>(); + while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) { + values.add(readAsDouble(reader)); + } + reader.readEndArray(); + + try { + return new Position(values); + } catch (IllegalArgumentException e) { + throw new CodecConfigurationException(format("Invalid Position: %s", e.getMessage())); + } + } + + private static double readAsDouble(final BsonReader reader) { + if (reader.getCurrentBsonType() == BsonType.DOUBLE) { + return reader.readDouble(); + } else if (reader.getCurrentBsonType() == BsonType.INT32) { + return reader.readInt32(); + } else if (reader.getCurrentBsonType() == BsonType.INT64) { + return reader.readInt64(); + } + + throw new CodecConfigurationException("A GeoJSON position value must be a numerical type, but the value is of type " + + reader.getCurrentBsonType()); + } + + private void encodeLinearRing(final List ring, final BsonWriter writer) { + writer.writeStartArray(); + for (Position position : ring) { + encodePosition(writer, position); + } + writer.writeEndArray(); + } + + private void encodePosition(final BsonWriter writer, final Position value) { + writer.writeStartArray(); + + for (double number : value.getValues()) { + writer.writeDouble(number); + } + + writer.writeEndArray(); + } + + private static void validateIsArray(final BsonReader reader) { + if (reader.getCurrentBsonType() != BsonType.ARRAY) { + throw new CodecConfigurationException("Invalid BsonType expecting an Array"); + } + } + +} diff --git a/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java b/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java new file mode 100644 index 00000000000..4c1ced256c7 --- /dev/null +++ b/core/src/main/java/dev/morphia/mapping/codec/filters/GeoWithinFilterCodec.java @@ -0,0 +1,62 @@ +package dev.morphia.mapping.codec.filters; + +import com.mongodb.client.model.geojson.CoordinateReferenceSystem; +import com.mongodb.client.model.geojson.GeoJsonObjectType; +import com.mongodb.client.model.geojson.Geometry; +import com.mongodb.client.model.geojson.MultiPolygon; +import com.mongodb.client.model.geojson.Polygon; + +import dev.morphia.MorphiaDatastore; +import dev.morphia.query.filters.GeoWithinFilter; + +import org.bson.BsonWriter; +import org.bson.codecs.EncoderContext; + +import static dev.morphia.mapping.codec.CodecHelper.document; +import static dev.morphia.mapping.codec.CodecHelper.value; + +public class GeoWithinFilterCodec extends BaseFilterCodec { + public GeoWithinFilterCodec(MorphiaDatastore datastore) { + super(datastore); + } + + @Override + public void encode(BsonWriter writer, GeoWithinFilter value, EncoderContext encoderContext) { + document(writer, value.path(datastore.getMapper()), () -> { + if (value.isNot()) { + document(writer, "$not", () -> { + encodeFilter(writer, value, encoderContext); + }); + } else { + encodeFilter(writer, value, encoderContext); + } + }); + } + + private void encodeFilter(BsonWriter writer, GeoWithinFilter value, EncoderContext encoderContext) { + document(writer, value.getName(), () -> { + document(writer, "$geometry", () -> { + Geometry geometry = (Geometry) value.getValue(); + value(writer, "type", geometry.getType().getTypeName()); + GeoJsonObjectType type = geometry.getType(); + if (type == GeoJsonObjectType.POLYGON) { + var coordinates = ((Polygon) geometry).getCoordinates(); + value(datastore.getCodecRegistry(), writer, "coordinates", coordinates, encoderContext); + } else if (type == GeoJsonObjectType.MULTI_POLYGON) { + var coordinates = ((MultiPolygon) geometry).getCoordinates(); + value(datastore.getCodecRegistry(), writer, "coordinates", coordinates, encoderContext); + } + CoordinateReferenceSystem crs = geometry.getCoordinateReferenceSystem(); + if (crs != null) { + value(datastore.getCodecRegistry(), writer, "crs", crs, encoderContext); + } + + }); + }); + } + + @Override + public Class getEncoderClass() { + return GeoWithinFilter.class; + } +} diff --git a/core/src/main/java/dev/morphia/query/filters/Filter.java b/core/src/main/java/dev/morphia/query/filters/Filter.java index 1a29069eed1..6dca4062c3b 100644 --- a/core/src/main/java/dev/morphia/query/filters/Filter.java +++ b/core/src/main/java/dev/morphia/query/filters/Filter.java @@ -106,6 +106,7 @@ public Filter not() { * @hidden * @morphia.internal */ + @Nullable @MorphiaInternal public String getName() { return name; diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java index fa9849e8fc2..db9ad9b9724 100644 --- a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnyClear.java @@ -5,16 +5,28 @@ import static dev.morphia.query.filters.Filters.bitsAnyClear; public class TestBitsAnyClear extends FilterTest { + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example1 + * + */ @Test(testName = "Bit Position Array") public void testExample1() { testQuery((query) -> query.filter(bitsAnyClear("a", new int[] { 1, 5 }))); } + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example2 + * + */ @Test(testName = "Integer Bitmask") public void testExample2() { testQuery((query) -> query.filter(bitsAnyClear("a", 35))); } + /** + * test data: dev/morphia/test/query/filters/bitsAnyClear/example3 + * + */ @Test(testName = "BinData Bitmask") public void testExample3() { testQuery((query) -> query.filter(bitsAnyClear("a", new byte[] { 48 }))); diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java index 8f473a9912e..b6559246bd0 100644 --- a/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBitsAnySet.java @@ -5,22 +5,31 @@ import static dev.morphia.query.filters.Filters.bitsAnySet; public class TestBitsAnySet extends FilterTest { + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example1 + * + */ @Test(testName = "Bit Position Array") public void testExample1() { - testQuery((query) -> query.filter( - bitsAnySet("a", new int[] { 1, 5 }))); + testQuery((query) -> query.filter(bitsAnySet("a", new int[] { 1, 5 }))); } + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example2 + * + */ @Test(testName = "Integer Bitmask") public void testExample2() { - testQuery((query) -> query.filter( - bitsAnySet("a", 35))); + testQuery((query) -> query.filter(bitsAnySet("a", 35))); } + /** + * test data: dev/morphia/test/query/filters/bitsAnySet/example3 + * + */ @Test(testName = "BinData Bitmask") public void testExample3() { - testQuery((query) -> query.filter( - bitsAnySet("a", new byte[] { 48 }))); + testQuery((query) -> query.filter(bitsAnySet("a", new byte[] { 48 }))); } } diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestBox.java b/core/src/test/java/dev/morphia/test/query/filters/TestBox.java new file mode 100644 index 00000000000..d74b2085eff --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestBox.java @@ -0,0 +1,23 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.box; + +public class TestBox extends FilterTest { + + /** + * test data: dev/morphia/test/query/filters/box/example1 + */ + @Test(testName = "main") + public void testExample1() { + Point bottomLeft = new Point(new Position(0, 0)); + Point upperRight = new Point(new Position(100, 100)); + testQuery(new QueryTestOptions().skipDataCheck(true), + (query) -> query.filter( + box("loc", bottomLeft, upperRight))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java b/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java index 992a4fd3eb1..c1788c236fe 100644 --- a/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java +++ b/core/src/test/java/dev/morphia/test/query/filters/TestElemMatch.java @@ -8,16 +8,28 @@ import static dev.morphia.query.filters.Filters.lt; public class TestElemMatch extends FilterTest { + /** + * test data: dev/morphia/test/query/filters/elemMatch/example1 + * + */ @Test(testName = "Element Match") public void testExample1() { testQuery((query) -> query.filter(elemMatch("results", gte(80), lt(85)))); } + /** + * test data: dev/morphia/test/query/filters/elemMatch/example2 + * + */ @Test(testName = "Array of Embedded Documents") public void testExample2() { testQuery((query) -> query.filter(elemMatch("results", eq("product", "xyz"), gte("score", 8)))); } + /** + * test data: dev/morphia/test/query/filters/elemMatch/example3 + * + */ @Test(testName = "Single Query Condition") public void testExample3() { testQuery((query) -> query.filter(elemMatch("results", eq("product", "xyz")))); diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestEq.java b/core/src/test/java/dev/morphia/test/query/filters/TestEq.java index e82cd2c8b59..be01c8f7d7e 100644 --- a/core/src/test/java/dev/morphia/test/query/filters/TestEq.java +++ b/core/src/test/java/dev/morphia/test/query/filters/TestEq.java @@ -8,21 +8,37 @@ import static dev.morphia.query.filters.Filters.eq; public class TestEq extends FilterTest { + /** + * test data: dev/morphia/test/query/filters/eq/example1 + * + */ @Test(testName = "Equals a Specified Value") public void testExample1() { testQuery((query) -> query.filter(eq("qty", 20))); } + /** + * test data: dev/morphia/test/query/filters/eq/example2 + * + */ @Test(testName = "Field in Embedded Document Equals a Value") public void testExample2() { testQuery((query) -> query.filter(eq("item.name", "ab"))); } + /** + * test data: dev/morphia/test/query/filters/eq/example3 + * + */ @Test(testName = "Array Element Equals a Value") public void testExample3() { testQuery((query) -> query.filter(eq("tags", "B"))); } + /** + * test data: dev/morphia/test/query/filters/eq/example4 + * + */ @Test(testName = "Equals an Array Value") public void testExample4() { testQuery((query) -> query.filter(eq("tags", List.of("A", "B")) @@ -30,6 +46,10 @@ public void testExample4() { )); } + /** + * test data: dev/morphia/test/query/filters/eq/example5 + * + */ @Test(testName = "Regex Match Behaviour") public void testExample5() { testQuery(new QueryTestOptions().removeIds(true), diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java b/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java new file mode 100644 index 00000000000..b5fea2fca01 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGeoWithin.java @@ -0,0 +1,56 @@ +package dev.morphia.test.query.filters; + +import java.util.List; + +import com.mongodb.client.model.geojson.NamedCoordinateReferenceSystem; +import com.mongodb.client.model.geojson.Polygon; +import com.mongodb.client.model.geojson.PolygonCoordinates; +import com.mongodb.client.model.geojson.Position; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.geoWithin; + +public class TestGeoWithin extends FilterTest { + + /** + * test data: dev/morphia/test/query/filters/geoWithin/example1 + * + * db.places.find( { loc: { $geoWithin: { $geometry: { type : "Polygon" , + * coordinates: [ [ [ 0, 0 ], [ 3, 6 ], [ 6, 1 ], [ 0, 0 ] ] ] } } } } ) + */ + @Test(testName = "Within a Polygon") + public void testExample1() { + var points = List.of( + new Position(0, 0), + new Position(3, 6), + new Position(6, 1), + new Position(0, 0)); + testQuery(new QueryTestOptions().skipDataCheck(true), + (query) -> query.filter( + geoWithin("loc", new Polygon(points)))); + } + + /** + * test data: dev/morphia/test/query/filters/geoWithin/example2 + * + * db.places.find( { loc: { $geoWithin: { $geometry: { type : "Polygon" , + * coordinates: [ [ [ -100, 60 ], [ -100, 0 ], [ -100, -60 ], [ 100, -60 ], [ + * 100, 60 ], [ -100, 60 ] ] ], crs: { type: "name", properties: { name: + * "urn:x-mongodb:crs:strictwinding:EPSG:4326" } } } } } } ) + */ + @Test(testName = "Within a \"Big\" Polygon") + public void testExample2() { + var coords = new PolygonCoordinates(List.of( + new Position(-100, 60), + new Position(-100, 0), + new Position(-100, -60), + new Position(100, -60), + new Position(100, 60), + new Position(-100, 60))); + testQuery(new QueryTestOptions().skipDataCheck(true), + (query) -> query.filter( + geoWithin("loc", + new Polygon(new NamedCoordinateReferenceSystem("urn:x-mongodb:crs:strictwinding:EPSG:4326"), coords)))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestGt.java b/core/src/test/java/dev/morphia/test/query/filters/TestGt.java new file mode 100644 index 00000000000..cc088e1da0c --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestGt.java @@ -0,0 +1,20 @@ +package dev.morphia.test.query.filters; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.gt; + +public class TestGt extends FilterTest { + + /** + * test data: dev/morphia/test/query/filters/gt/example1 + * + * db.inventory.find( { quantity: { $gt: 20 } } ) + */ + @Test(testName = "Match Document Fields") + public void testExample1() { + testQuery(new QueryTestOptions().removeIds(true), + (query) -> query.filter( + gt("quantity", 20))); + } +} \ No newline at end of file diff --git a/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java b/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java new file mode 100644 index 00000000000..498852a3bd2 --- /dev/null +++ b/core/src/test/java/dev/morphia/test/query/filters/TestPolygon.java @@ -0,0 +1,26 @@ +package dev.morphia.test.query.filters; + +import com.mongodb.client.model.geojson.Point; +import com.mongodb.client.model.geojson.Position; + +import org.testng.annotations.Test; + +import static dev.morphia.query.filters.Filters.polygon; + +public class TestPolygon extends FilterTest { + + /** + * test data: dev/morphia/test/query/filters/polygon/example1 + */ + @Test(testName = "main") + public void testExample1() { + Point[] point = new Point[] { + new Point(new Position(0, 0)), + new Point(new Position(3, 6)), + new Point(new Position(6, 0)), + }; + testQuery(new QueryTestOptions().skipDataCheck(true), + (query) -> query.filter( + polygon("loc", point))); + } +} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json new file mode 100644 index 00000000000..526415b934d --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/action.json @@ -0,0 +1,3 @@ +db.places.find( { + loc: { $geoWithin: { $box: [ [ 0.0, 0.0 ], [ 100.0, 100.0 ] ] } } +} ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/box/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json new file mode 100644 index 00000000000..f4f09153ae4 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/action.json @@ -0,0 +1,12 @@ +db.places.find( + { + loc: { + $geoWithin: { + $geometry: { + type : "Polygon" , + coordinates: [ [ [ 0.0, 0.0 ], [ 3.0, 6.0 ], [ 6.0, 1.0 ], [ 0.0, 0.0 ] ] ] + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name new file mode 100644 index 00000000000..c6c78533878 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example1/name @@ -0,0 +1 @@ +Within a Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json new file mode 100644 index 00000000000..4b0b9f23f57 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/action.json @@ -0,0 +1,20 @@ +db.places.find( + { + loc: { + $geoWithin: { + $geometry: { + type : "Polygon" , + coordinates: [ + [ + [ -100.0, 60.0 ], [ -100.0, 0.0 ], [ -100.0, -60.0 ], [ 100.0, -60.0 ], [ 100.0, 60.0 ], [ -100.0, 60.0 ] + ] + ], + crs: { + type: "name", + properties: { name: "urn:x-mongodb:crs:strictwinding:EPSG:4326" } + } + } + } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name new file mode 100644 index 00000000000..8dedd8cb80c --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/geoWithin/example2/name @@ -0,0 +1 @@ +Within a "Big" Polygon \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json new file mode 100644 index 00000000000..646a46eec7b --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/action.json @@ -0,0 +1 @@ +db.inventory.find( { quantity: { $gt: 20 } } ) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json new file mode 100644 index 00000000000..c1d2781b7de --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/data.json @@ -0,0 +1,3 @@ +{ "item": "nuts", "quantity": 30, "carrier": { "name": "Shipit", "fee": 3 } }, +{ "item": "bolts", "quantity": 50, "carrier": { "name": "Shipit", "fee": 4 } }, +{ "item": "washers", "quantity": 10, "carrier": { "name": "Shipit", "fee": 1 } } \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json new file mode 100644 index 00000000000..b74d8405248 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/expected.json @@ -0,0 +1,2 @@ +{ _id: ObjectId("61ba25cbfe687fce2f042414"), item: 'nuts', quantity: 30, carrier: { name: 'Shipit', fee: 3 }}, +{ _id: ObjectId("61ba25cbfe687fce2f042415"), item: 'bolts', quantity: 50, carrier: { name: 'Shipit', fee: 4 }} \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name new file mode 100644 index 00000000000..f19ec4ead4e --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/gt/example1/name @@ -0,0 +1 @@ +Match Document Fields \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json new file mode 100644 index 00000000000..513ba08de93 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/action.json @@ -0,0 +1,7 @@ +db.places.find( + { + loc: { + $geoWithin: { $polygon: [ [ 0.0 , 0.0 ], [ 3.0 , 6.0 ], [ 6.0 , 0.0 ] ] } + } + } +) \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock new file mode 100644 index 00000000000..0e9ec60ef85 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/lock @@ -0,0 +1 @@ +converted the point values to doubles \ No newline at end of file diff --git a/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name new file mode 100644 index 00000000000..88d050b1908 --- /dev/null +++ b/core/src/test/resources/dev/morphia/test/query/filters/polygon/example1/name @@ -0,0 +1 @@ +main \ No newline at end of file