diff --git a/persistence-modules/java-mongodb-queries/README.md b/persistence-modules/java-mongodb-queries/README.md
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/persistence-modules/java-mongodb-queries/pom.xml b/persistence-modules/java-mongodb-queries/pom.xml
new file mode 100644
index 0000000000..731d61f013
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/pom.xml
@@ -0,0 +1,34 @@
+
+
+
+ parent-modules
+ com.baeldung
+ 1.0.0-SNAPSHOT
+ ../../pom.xml
+
+ 4.0.0
+
+ java-mongodb-queries
+
+
+
+ org.mongodb
+ mongodb-driver-sync
+ 4.6.0
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ 5.8.1
+ compile
+
+
+
+
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java
new file mode 100644
index 0000000000..b71b88406d
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/CrudClient.java
@@ -0,0 +1,183 @@
+package com.baeldung.mongo.crud;
+
+import com.baeldung.mongo.crud.model.Event;
+import com.mongodb.BasicDBObject;
+import com.mongodb.BasicDBObjectBuilder;
+import com.mongodb.MongoException;
+import com.mongodb.client.MongoClient;
+import com.mongodb.client.MongoClients;
+import com.mongodb.client.MongoCollection;
+import com.mongodb.client.MongoDatabase;
+import com.mongodb.client.model.UpdateOptions;
+import com.mongodb.client.model.Updates;
+import com.mongodb.client.result.InsertOneResult;
+import com.mongodb.client.result.DeleteResult;
+import com.mongodb.client.result.UpdateResult;
+import org.bson.BsonValue;
+import org.bson.Document;
+import org.bson.codecs.configuration.CodecProvider;
+import org.bson.codecs.configuration.CodecRegistry;
+import org.bson.codecs.pojo.PojoCodecProvider;
+import org.bson.conversions.Bson;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.ZoneId;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.MongoClientSettings.getDefaultCodecRegistry;
+import static com.mongodb.client.model.Filters.gte;
+import static com.mongodb.client.model.Filters.lt;
+import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
+import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
+
+public class CrudClient {
+
+ private static String uri = "mongodb://localhost:27017";
+ private static MongoClient mongoClient = MongoClients.create(uri);
+ private static MongoDatabase db;
+ private static MongoCollection collection;
+
+ public static OffsetDateTime offsetDateTime = OffsetDateTime.of(LocalDateTime.of(2022, 6, 4, 11, 0, 0),
+ ZoneOffset.ofHours(2));
+
+ public static Event pianoLessons = new Event(
+ "Piano lessons",
+ "Foo Bvld",
+ LocalDateTime.of(2022, 6, 4, 11, 0, 0));
+
+ public static Event soccerGame = new Event(
+ "Soccer game",
+ "Bar Avenue",
+ LocalDateTime.of(2022, 6, 10, 17, 0, 0));
+
+ public static Event pianoLessonsTZ = new Event(
+ "Piano lessons",
+ "Baz Bvld",
+ LocalDateTime.of(2022, 12, 31, 12, 0, 0),
+ ZoneOffset.ofHours(2).toString());
+
+ public static LocalDateTime dateQuery = LocalDateTime.of(2022, 6, 10, 17, 0, 0);
+ public static LocalDateTime dateQueryEventWithTZ = LocalDateTime.of(2022, 12, 31, 12, 0, 0);
+
+ public static LocalDateTime from = LocalDateTime.of(2022, 06, 04, 12, 0, 0);
+ public static LocalDateTime to = LocalDateTime.of(2022, 06, 10, 17, 0, 0);
+
+ public static LocalDate updateManyFrom = LocalDate.of(2022, 1, 1);
+ public static LocalDate updateManyTo = LocalDate.of(2023, 1, 1);
+
+ public static LocalDate deleteFrom = LocalDate.of(2022, 1, 1);
+ public static LocalDate deleteTo = LocalDate.of(2023, 01, 01);
+
+ public static void setup() {
+ CodecProvider codecProvider = PojoCodecProvider.builder().automatic(true).build();
+ CodecRegistry codecRegistry = fromRegistries(getDefaultCodecRegistry(), fromProviders(codecProvider));
+
+ db = mongoClient.getDatabase("calendar").withCodecRegistry(codecRegistry);
+ collection = db.getCollection("my_events", Event.class);
+ }
+
+ public static void close() {
+ mongoClient.close();
+ }
+
+ public static BsonValue insertEventsWithDate(Event e) {
+ try {
+ InsertOneResult insertResult = collection.insertOne(e);
+ return insertResult.getInsertedId();
+ } catch (MongoException me) {
+ System.err.println("Failed to insert with error: " + me);
+ throw me;
+ }
+ }
+
+ public static Event readEventsByDate(LocalDateTime localDateTime) {
+ try {
+ Event event = collection
+ .find(eq("dateTime", localDateTime))
+ .first();
+ return event;
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static List readEventsByDateRange(LocalDateTime from, LocalDateTime to) {
+ BasicDBObject object = new BasicDBObject();
+ object.put("dateTime", BasicDBObjectBuilder
+ .start("$gte", from)
+ .add("$lte", to)
+ .get());
+ try {
+ List list = new ArrayList(collection.find(object).into(new ArrayList()));
+ return list;
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static LocalDateTime readEventsByDateWithTZ(LocalDateTime localDateTime) {
+ try {
+ Event event = collection
+ .find(eq("dateTime", localDateTime))
+ .first();
+ OffsetDateTime offsetDateTime = OffsetDateTime.of(event.dateTime, ZoneOffset.of(pianoLessonsTZ.timeZoneOffset));
+ ZonedDateTime zoned = offsetDateTime.atZoneSameInstant(ZoneId.of("America/Toronto"));
+ return zoned.toLocalDateTime();
+ } catch (MongoException me) {
+ System.err.println("Failed to read with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long updateDateField() {
+ Document document = new Document().append("title", "Piano lessons");
+ Bson update = Updates.currentDate("updatedAt");
+ UpdateOptions options = new UpdateOptions().upsert(false);
+ try {
+ UpdateResult result = collection.updateOne(document, update, options);
+ return result.getModifiedCount();
+ } catch (MongoException me) {
+ System.err.println("Failed to update with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long updateManyEventsWithDateCriteria(LocalDate updateManyFrom, LocalDate updateManyTo) {
+ Bson query = and(gte("dateTime", updateManyFrom), lt("dateTime", updateManyTo));
+ Bson updates = Updates.currentDate("dateTime");
+ try {
+ UpdateResult result = collection.updateMany(query, updates);
+ return result.getModifiedCount();
+ } catch(MongoException me) {
+ System.err.println("Failed to replace/update with error: " + me);
+ throw me;
+ }
+ }
+
+ public static long deleteEventsByDate(LocalDate from, LocalDate to) {
+ Bson query = and(gte("dateTime", from), lt("dateTime", to));
+ try {
+ DeleteResult result = collection.deleteMany(query);
+ return result.getDeletedCount();
+ } catch (MongoException me) {
+ System.err.println("Failed to delete with error: " + me);
+ throw me;
+ }
+ }
+
+ public static void dropDb() {
+ db.drop();
+ }
+
+ public static void main(String[] args) {
+ }
+}
diff --git a/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java
new file mode 100644
index 0000000000..751dc5d6eb
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/main/java/com.baeldung.mongo/crud/model/Event.java
@@ -0,0 +1,28 @@
+package com.baeldung.mongo.crud.model;
+
+import java.time.LocalDateTime;
+
+public class Event {
+ public String title;
+ public String location;
+ public LocalDateTime dateTime;
+ public String timeZoneOffset;
+
+ public Event() {}
+ public Event(String title, String location, LocalDateTime dateTime) {
+ this.title = title;
+ this.location = location;
+ this.dateTime = dateTime;
+ }
+
+ public Event(String title, String location, LocalDateTime dateTime, String timeZoneOffset) {
+ this.title = title;
+ this.location = location;
+ this.dateTime = dateTime;
+ this.timeZoneOffset = timeZoneOffset;
+ }
+
+ @Override
+ public String toString() { return "\nEvent: " + title + "\nWhere: " + location + "\nWhen: " + dateTime; }
+}
+
diff --git a/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java b/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java
new file mode 100644
index 0000000000..db2f35f634
--- /dev/null
+++ b/persistence-modules/java-mongodb-queries/src/test/java/com.baeldung.mongo.crud/CrudClientLiveTest.java
@@ -0,0 +1,87 @@
+package com.baeldung.mongo.crud;
+
+import com.baeldung.mongo.crud.model.Event;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import java.io.IOException;
+import java.util.List;
+
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class CrudClientLiveTest {
+
+ @BeforeAll
+ public static void setup() {
+ CrudClient.setup();
+ }
+
+ @Test
+ @Order(1)
+ public void whenInsertingEventsWithDate_thenCheckForDocument() {
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessons));
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.soccerGame));
+ }
+
+ @Test
+ @Order(2)
+ public void whenReadingEventsByDate_thenCheckForReturnedDocument() {
+ Assertions.assertNotNull(CrudClient.readEventsByDate(CrudClient.dateQuery));
+ }
+
+ @Test
+ @Order(3)
+ public void whenReadingEventsByDateRange_thenCheckForReturnedDocument() {
+ List events = CrudClient.readEventsByDateRange(CrudClient.from, CrudClient.to);
+ Assertions.assertNotNull(events);
+ Assertions.assertEquals(1, events.size());
+ }
+
+ @Test
+ @Order(5)
+ public void whenUpdatingEventsDateField_thenCheckUpdatedCount() {
+ Assertions.assertEquals(1, CrudClient.updateDateField());
+ }
+
+ @Test
+ @Order(6)
+ public void whenUpdatingManyEvents_thenCheckUpdatedCount() {
+ long updates = CrudClient.updateManyEventsWithDateCriteria(CrudClient.updateManyFrom, CrudClient.updateManyTo);
+ Assertions.assertTrue(1 < updates);
+ }
+
+ @Test
+ @Order(7)
+ public void whenDeletingEventsWithDate_thenCheckDeletedCount() {
+ Assertions.assertEquals(2, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo));
+ }
+
+ @Test
+ @Order(8)
+ public void whenInsertingEventWithDateAndTimeZone_thenCheckForDocument() {
+ Assertions.assertNotNull(CrudClient.insertEventsWithDate(CrudClient.pianoLessonsTZ));
+ }
+
+ @Test
+ @Order(9)
+ public void whenReadingEventsWithDateAndTimeZone_thenCheckInsertedCount() {
+ Assertions.assertNotEquals(CrudClient.pianoLessonsTZ.dateTime, CrudClient.readEventsByDateWithTZ(CrudClient.dateQueryEventWithTZ));
+ }
+
+ @Test
+ @Order(10)
+ public void whenDeletingEventsWithDateAndTimeZone_thenCheckDeletedCount() {
+ Assertions.assertEquals(1, CrudClient.deleteEventsByDate(CrudClient.deleteFrom, CrudClient.deleteTo));
+ }
+
+ @AfterAll
+ public static void close() throws IOException {
+ CrudClient.dropDb();
+ CrudClient.close();
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 0801fbab46..046f59de53 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,10 @@
com.baeldung
parent-modules
1.0.0-SNAPSHOT
- parent-modules
+
+ persistence-modules/java-mongodb-queries
+
+ parent-modules
pom