### Quick start with ZIO Source: https://github.com/kirill5k/mongo4cats/blob/master/website/src/pages/home.mdx Example demonstrating database connection, document insertion, and filtered querying using ZIO layers. ```scala import mongo4cats.bson.Document import mongo4cats.bson.syntax._ import mongo4cats.operations.{Filter, Projection} import mongo4cats.zio.{ZMongoClient, ZMongoCollection, ZMongoDatabase} import zio._ object Zio extends ZIOAppDefault { val client = ZLayer.scoped[Any](ZMongoClient.fromConnectionString("mongodb://localhost:27017")) val database = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoClient](_.getDatabase("my-db"))) val collection = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoDatabase](_.getCollection("docs"))) val program = for { coll <- ZIO.service[ZMongoCollection[Document]] _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) docs <- coll.find .filter(Filter.gte("index", 10) && Filter.regex("name", "doc-[1-9]0")) .projection(Projection.excludeId) .sortByDesc("name") .limit(5) .all _ <- Console.printLine(docs.mkString("[", ", ", "]")) } yield () override def run = program.provide(client, database, collection) } ``` -------------------------------- ### Quick start with Cats Effect Source: https://github.com/kirill5k/mongo4cats/blob/master/website/src/pages/home.mdx Example demonstrating database connection, document insertion, and filtered querying using Cats Effect. ```scala import cats.effect.{IO, IOApp} import mongo4cats.client.MongoClient import mongo4cats.operations.{Filter, Projection} import mongo4cats.bson.Document import mongo4cats.bson.syntax._ object Quickstart extends IOApp.Simple { override val run: IO[Unit] = MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) docs <- coll.find .filter(Filter.gte("index", 10) && Filter.regex("name", "doc-[1-9]0")) .projection(Projection.excludeId) .sortByDesc("name") .limit(5) .all _ <- IO.println(docs.mkString("[", ", ", "]")) } yield () } } ``` -------------------------------- ### Quick Start with ZIO Source: https://github.com/kirill5k/mongo4cats/blob/master/readme.md This example shows how to connect to MongoDB, insert documents, and query them using mongo4cats with ZIO. It sets up ZLayers for the client, database, and collection. Ensure MongoDB is running on localhost:27017. ```scala import mongo4cats.bson.Document import mongo4cats.bson.syntax._ import mongo4cats.operations.{Filter, Projection} import mongo4cats.zio.{ZMongoClient, ZMongoCollection, ZMongoDatabase} import zio._ object Zio extends ZIOAppDefault { val client = ZLayer.scoped[Any](ZMongoClient.fromConnectionString("mongodb://localhost:27017")) val database = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoClient](_.getDatabase("my-db"))) val collection = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoDatabase](_.getCollection("docs"))) val program = for { coll <- ZIO.service[ZMongoCollection[Document]] _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) docs <- coll.find .filter(Filter.gte("index", 10) && Filter.regex("name", "doc-[1-9]0")) .projection(Projection.excludeId) .sortByDesc("name") .limit(5) .all _ <- Console.printLine(docs.mkString("[ ", ",\n", "\n]")) } yield () override def run = program.provide(client, database, collection) } ``` -------------------------------- ### Start local development server Source: https://github.com/kirill5k/mongo4cats/blob/master/website/readme.md Launches a local server with live reloading for development purposes. ```bash $ yarn start ``` -------------------------------- ### Install dependencies Source: https://github.com/kirill5k/mongo4cats/blob/master/website/readme.md Run this command to install all required project dependencies. ```bash $ yarn ``` -------------------------------- ### Quick Start with Cats Effect Source: https://github.com/kirill5k/mongo4cats/blob/master/readme.md This example demonstrates connecting to MongoDB, inserting documents, and querying them using mongo4cats with Cats Effect. Ensure MongoDB is running on localhost:27017. ```scala import cats.effect.{IO, IOApp} import mongo4cats.client.MongoClient import mongo4cats.operations.{Filter, Projection} import mongo4cats.bson.Document import mongo4cats.bson.syntax._ object Quickstart extends IOApp.Simple { override val run: IO[Unit] = MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) docs <- coll.find .filter(Filter.gte("index", 10) && Filter.regex("name", "doc-[1-9]0")) .projection(Projection.excludeId) .sortByDesc("name") .limit(5) .all _ <- IO.println(docs.mkString("[ ", ",\n", "\n]")) } yield () } ``` -------------------------------- ### Perform ACID Transactions in Scala Source: https://context7.com/kirill5k/mongo4cats/llms.txt Demonstrates starting, committing, and aborting multi-document transactions using Cats Effect IO. ```scala import cats.effect.IO import cats.syntax.foldable._ import mongo4cats.client.MongoClient import mongo4cats.bson.Document import mongo4cats.bson.syntax._ MongoClient.fromConnectionString[IO]("mongodb://localhost:27017/?retryWrites=false").use { client => for { db <- client.getDatabase("my-db") _ <- client.startSession.use { session => for { coll <- db.getCollection("docs") // Start a transaction _ <- session.startTransaction // Perform operations within the transaction _ <- (0 to 99).toList.traverse_(i => coll.insertOne(session, Document("name" := s"doc-$i")) ) // Abort transaction - changes are rolled back _ <- session.abortTransaction count1 <- coll.count _ <- IO.println(s"Count after abort: $count1") // 0 // Start new transaction _ <- session.startTransaction _ <- (0 to 99).toList.traverse_(i => coll.insertOne(session, Document("name" := s"doc-$i")) ) // Commit transaction - changes are persisted _ <- session.commitTransaction count2 <- coll.count _ <- IO.println(s"Count after commit: $count2") // 100 } yield () } } yield () } ``` -------------------------------- ### JSON to BSON Conversion Example Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/circe.md Demonstrates converting a Scala case class with various data types to a MongoDB Document and back using Circe codecs. Ensure Encoder[T] and Decoder[T] instances are in the implicit scope. ```scala import io.circe.generic.auto._ import mongo4cats.bson.{Document, ObjectId} import mongo4cats.circe._ import mongo4cats.bson.syntax._ import java.time.Instant final case class MyClass( _id: ObjectId, dateField: Instant, stringField: String, intField: Int, longField: Long, arrayField: List[String], optionField: Option[String] ) val myClass = MyClass( _id = ObjectId.gen, dateField = Instant.now(), stringField = "string", intField = 1, longField = 1660999000L, arrayField = List("item1", "item2"), optionField = None ) val doc = Document("_id" := ObjectId.gen, "myClasses" := List(myClass)) val jsonString = doc.toJson //{ // "_id": { // "$oid": "6300e54d64332103430291d3" // }, // "myClasses": [ // { // "_id": { // "$oid": "6300e54d64332103430291d2" // }, // "dateField": { // "$date": "2022-08-20T13:44:45.736Z" // }, // "stringField": "string", // "intField": 1, // "longField": 1660999000, // "arrayField": [ // "item1", // "item2" // ], // "optionField": null // } // ] //} val retrievedMyClasses = doc.getAs[List[MyClass]]("myClasses") //Some(List(MyClass(6300e54d64332103430291d2,2022-08-20T13:44:45.736633Z,string,1,1660999000,List(item1, item2),None))) ``` -------------------------------- ### Create a Change Stream on a Collection Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/watch.md Use this to monitor all changes in a collection. No additional setup is required beyond having a `MongoCollection` instance. ```scala import mongo4cats.bson.Document val changes: fs2.Stream[IO, Document] = collection.watch.stream ``` -------------------------------- ### Run Embedded MongoDB with Default Port Source: https://context7.com/kirill5k/mongo4cats/llms.txt Use `withRunningEmbeddedMongo` to start an embedded MongoDB instance. Override `mongoPort` to change the default port. This is useful for unit tests requiring a disposable database. ```scala import cats.effect.IO import cats.effect.unsafe.implicits.global import mongo4cats.bson.Document import mongo4cats.bson.syntax._ import mongo4cats.client.MongoClient import mongo4cats.embedded.EmbeddedMongo import org.scalatest.matchers.must.Matchers import org.scalatest.wordspec.AsyncWordSpec class WithEmbeddedMongoSpec extends AsyncWordSpec with Matchers with EmbeddedMongo { // Override default port (27017) override val mongoPort: Int = 12345 "A MongoCollection" should { "create and retrieve documents from a db" in withRunningEmbeddedMongo { MongoClient.fromConnectionString[IO]("mongodb://localhost:12345").use { client => for { db <- client.getDatabase("testdb") coll <- db.getCollection("docs") testDoc = Document("Hello" := "World!") _ <- coll.insertOne(testDoc) foundDoc <- coll.find.first } yield foundDoc mustBe Some(testDoc) } }.unsafeToFuture() // Pass connection properties explicitly "start instance on different port" in withRunningEmbeddedMongo("localhost", 12355) { MongoClient.fromConnectionString[IO]("mongodb://localhost:12355").use { client => for { db <- client.getDatabase("testdb") coll <- db.getCollection("docs") testDoc = Document("Hello" := "World!") _ <- coll.insertOne(testDoc) foundDoc <- coll.find.first } yield foundDoc mustBe Some(testDoc) } }.unsafeToFuture() } } ``` -------------------------------- ### Use Codec Provider with MongoCollection Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/circe.md Add the derived codec provider to the codec registry when getting a MongoCollection to enable automatic encoding and decoding of your case class. ```scala import cats.effect.IO import mongo4cats.collection.MongoCollection val collection: IO[MongoCollection[IO, MyClass]] = database.getCollectionWithCodec[MyClass]("mycoll") ``` -------------------------------- ### Stream Documents from Collection Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/find.md Use `find.stream` to get an fs2.Stream of Document objects from a collection. ```scala import mongo4cats.bson.Document val data: fs2.Stream[IO, Document] = collection.find.stream ``` -------------------------------- ### Get Distinct Values from Collection Source: https://context7.com/kirill5k/mongo4cats/llms.txt Retrieve unique values for a specified field. Supports streaming and custom codecs for typed results. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.bson.Document MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") // Get distinct string values distinctStrings: Iterable[String] <- coll.distinct[String]("category").all // Stream distinct values distinctStream = coll.distinct[String]("category").stream // fs2.Stream[IO, String] // Get distinct nested documents distinctDocs: Iterable[Document] <- coll.distinct[Document]("metadata").all // Get distinct values with custom codec (requires MongoCodecProvider in scope) distinctTyped: Iterable[MyClass] <- coll.distinctWithCodec[MyClass]("nested").all // Add codecs explicitly distinctWithCodec <- coll.withAddedCodec(myClassCodecs).distinct[MyClass]("nested").all } yield () } ``` -------------------------------- ### Instantiate MongoClient using various connection methods Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/connection.md Demonstrates creating a MongoClient instance using connection strings, server addresses, explicit connection objects, or custom settings. All methods return a Resource[F, MongoClient[F]] for proper lifecycle management. ```scala import cats.effect.IO import mongo4cats.models.client._ import mongo4cats.client._ // From a connection string val clientFromConnString = MongoClient.fromConnectionString[IO]("mongodb://localhost:27017") // By providing ServerAddress val clientFromServerAddress = MongoClient.fromServerAddress[IO](ServerAddress("localhost", 27017)) // By providing Connection val connection = MongoConnection("localhost", 27017, Some(MongoCredential("username", "password")), MongoConnectionType.Classic) val clientFromConnection = MongoClient.fromConnection[IO](connection) // By providing custom MongoClientSettings object val settings = MongoClientSettings.builder().applyConnectionString(ConnectionString("mongodb://localhost:27017")).build() val clientFromSettings = MongoClient.create[IO](settings) ``` -------------------------------- ### Build static site Source: https://github.com/kirill5k/mongo4cats/blob/master/website/readme.md Generates the static website files in the build directory. ```bash $ yarn build ``` -------------------------------- ### Import ZIO module Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/zio.md Import essential classes for ZIO integration. ```scala import mongo4cats.zio._ ``` -------------------------------- ### Perform Pipeline Aggregations Source: https://context7.com/kirill5k/mongo4cats/llms.txt Shows how to build and execute aggregation pipelines, including grouping, lookups, sorting, and streaming results. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.operations.{Accumulator, Aggregate, Sort} import mongo4cats.bson.Document MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("transactions") // Build accumulator for grouping accumulator = Accumulator .sum("count", 1) // count documents in group .sum("totalAmount", "$amount") // sum amounts .first("categoryId", "$category._id") // get first category id .avg("avgAmount", "$amount") // calculate average // Build aggregation pipeline aggregation = Aggregate .group("$category", accumulator) // group by category .lookup("categories", "categoryId", "_id", "category") // join with categories .sort(Sort.desc("totalAmount")) // sort results .limit(10) // limit output // Execute aggregation - get first result firstResult: Option[Document] <- coll.aggregate[Document](aggregation).first // Get all results as collection allResults: Iterable[Document] <- coll.aggregate[Document](aggregation).all // Stream results streamResults = coll.aggregate[Document](aggregation).stream // fs2.Stream[IO, Document] // Aggregate with typed result class typedResults <- coll.aggregateWithCodec[CategorySummary](aggregation).all // Write aggregation output to collection ($out stage) _ <- coll.aggregate[Document](Aggregate.out("output-collection")).toCollection } yield () } ``` -------------------------------- ### Create MongoClient Connections Source: https://context7.com/kirill5k/mongo4cats/llms.txt Initialize a MongoClient using connection strings, server addresses, or custom settings. Manage the client as a resource to ensure proper connection cleanup. ```scala import cats.effect.IO import mongo4cats.models.client._ import mongo4cats.client._ // From a connection string (most common) val clientFromConnString = MongoClient.fromConnectionString[IO]("mongodb://localhost:27017") // By providing ServerAddress val clientFromServerAddress = MongoClient.fromServerAddress[IO](ServerAddress("localhost", 27017)) // By providing Connection with credentials val connection = MongoConnection( "localhost", 27017, Some(MongoCredential("username", "password")), MongoConnectionType.Classic ) val clientFromConnection = MongoClient.fromConnection[IO](connection) // By providing custom MongoClientSettings val settings = MongoClientSettings.builder() .applyConnectionString(ConnectionString("mongodb://localhost:27017")) .build() val clientFromSettings = MongoClient.create[IO](settings) // Using the client with resource management MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("mydb") // work with database... } yield () } ``` -------------------------------- ### Connect to database and collections Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/zio.md Create ZLayers for ZMongoClient, ZMongoDatabase, and ZMongoCollection. ```scala import mongo4cats.zio._ val client = ZLayer.scoped[Any](ZMongoClient.fromConnectionString("mongodb://localhost:27017")) val database = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoClient](_.getDatabase("my-db"))) val collection = ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoDatabase](_.getCollection("docs"))) ``` -------------------------------- ### Create and Manipulate BSON Documents in Scala Source: https://context7.com/kirill5k/mongo4cats/llms.txt Demonstrates creating BSON documents using explicit BsonValue wrappers or the preferred := syntax for automatic conversion. Shows how to immutably update documents and retrieve values by type or nested path. Includes conversion to JSON. ```scala import mongo4cats.bson.{BsonValue, Document, ObjectId} import mongo4cats.bson.syntax._ import java.time.Instant // Creating documents with explicit BsonValue wrappers val doc1: Document = Document( "_id" -> BsonValue.objectId(ObjectId.gen), "null" -> BsonValue.Null, "string" -> BsonValue.string("str"), "int" -> BsonValue.int(1), "boolean" -> BsonValue.boolean(true), "double" -> BsonValue.double(2.0), "long" -> BsonValue.long(1660999000L), "dateTime" -> BsonValue.instant(Instant.now), "array" -> BsonValue.array(BsonValue.string("item1"), BsonValue.string("item2")), "nestedDocument" -> BsonValue.document(Document("field" -> BsonValue.string("nested"))) ) // Using := syntax for automatic conversion (preferred) val doc2: Document = Document( "_id" := ObjectId.gen, "string" := "str", "int" := 1, "boolean" := true, "double" := 2.0, "long" := 1660999000L, "dateTime" := Instant.now, "array" := List("item1", "item2", "item3"), "nestedDocument" := Document("field" := "nested") ) // Updating documents (returns new document - immutable) val updatedDoc = doc2.add("newField" -> "string") val anotherUpdate = doc2 += ("anotherField" := 42) // Retrieving values val stringField: Option[String] = doc2.getString("string") val typedField: Option[Int] = doc2.getAs[Int]("int") val arrayField: Option[List[String]] = doc2.getAs[List[String]]("array") val nestedField: Option[String] = doc2.getNestedAs[String]("nestedDocument.field") // Convert to JSON val json: String = doc2.toJson ``` -------------------------------- ### Import Circe Integration Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/circe.md Include this import to enable automatic derivation of MongoDB codecs from Circe codecs. ```scala import mongo4cats.circe._ ``` -------------------------------- ### Create BSON documents with syntax extensions Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/documents.md Uses the mongo4cats.bson.syntax package to enable the := operator for cleaner document construction. ```scala import mongo4cats.bson.syntax._ val doc: Document = Document( "_id" := ObjectId.gen, "null" := BsonValue.Null, "string" := "str", "int" := 1, "boolean" := true, "double" := 2.0, "int" := 1, "long" := 1660999000L, "dateTime" := Instant.now, "array" := List("item1", "item2", "item3"), "nestedDocument" := Document("field" := "nested") ) ``` -------------------------------- ### Deploy to GitHub Pages Source: https://github.com/kirill5k/mongo4cats/blob/master/website/readme.md Commands to deploy the site to the gh-pages branch, supporting both SSH and HTTPS authentication methods. ```bash $ USE_SSH=true yarn deploy ``` ```bash $ GIT_USER= yarn deploy ``` -------------------------------- ### Retrieve a MongoDatabase instance Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/connection.md Shows how to access a specific database from an active MongoClient instance. The database is created automatically upon the first query if it does not exist. ```scala import mongo4cats.database.MongoDatabase MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => val database: IO[MongoDatabase[IO]] = client.getDatabase("mydb") } ``` -------------------------------- ### Add Optional Dependencies (circe or zio-json) Source: https://github.com/kirill5k/mongo4cats/blob/master/readme.md Include these optional dependencies in your build.sbt to enable support for circe or zio-json. ```scala // circe libraryDependencies += "io.github.kirill5k" %% "mongo4cats-circe" % "" // zio-json libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-json" % "" ``` -------------------------------- ### Add mongo4cats Dependencies (ZIO 2) Source: https://github.com/kirill5k/mongo4cats/blob/master/readme.md Add these lines to your build.sbt to include the mongo4cats library and the embedded driver for testing when using ZIO 2. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio" % "" libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-embedded" % "" % Test ``` -------------------------------- ### Integrate Mongo4cats with ZIO Source: https://context7.com/kirill5k/mongo4cats/llms.txt Configures ZIO layers for MongoDB clients and demonstrates testing with an embedded MongoDB instance. ```scala import mongo4cats.bson._ import mongo4cats.bson.syntax._ import mongo4cats.zio._ import mongo4cats.zio.embedded.EmbeddedMongo import zio._ import zio.test._ import zio.test.Assertion._ // ZIO layer definitions for dependency injection val clientLayer = ZLayer.scoped[Any]( ZMongoClient.fromConnectionString("mongodb://localhost:27017") ) val databaseLayer = ZLayer.fromZIO( ZIO.serviceWithZIO[ZMongoClient](_.getDatabase("my-db")) ) val collectionLayer = ZLayer.fromZIO( ZIO.serviceWithZIO[ZMongoDatabase](_.getCollection("docs")) ) // Example ZIO test with embedded MongoDB object ZMongoCollectionSpec extends ZIOSpecDefault with EmbeddedMongo { override def spec = suite("A ZMongoCollection")( test("should store and retrieve documents") { withRunningEmbeddedMongo("localhost", 27017) { ZIO .serviceWithZIO[ZMongoDatabase] { db => for { coll <- db.getCollection("coll") doc = Document("_id" := ObjectId.gen, "name" := "test") _ <- coll.insertOne(doc) result <- coll.find.all } yield assert(result)(equalTo(List(doc))) } .provide( ZLayer.scoped(ZMongoClient.fromConnectionString("mongodb://localhost:27017")), ZLayer.fromZIO(ZIO.serviceWithZIO[ZMongoClient](_.getDatabase("my-db"))) ) } } ) } ``` -------------------------------- ### Access MongoDatabase and Collections Source: https://context7.com/kirill5k/mongo4cats/llms.txt Retrieve database instances and collections, optionally binding them to specific case classes using codecs. ```scala import cats.effect.IO import mongo4cats.bson.Document import mongo4cats.collection.MongoCollection import mongo4cats.database.MongoDatabase import mongo4cats.models.database.CreateCollectionOptions MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { // Get a database (created automatically if it doesn't exist) database <- client.getDatabase("mydb") // Get a collection with default Document type collection <- database.getCollection("mycoll") // Get a collection with a custom codec registry typedCollection <- database.getCollection[MyClass]("mycoll", myClassCodecRegistry) // Get a collection with implicit MongoCodecProvider codecCollection <- database.getCollectionWithCodec[MyClass]("mycoll") // Create a collection explicitly with options _ <- database.createCollection("capped-coll", CreateCollectionOptions().capped(true).sizeInBytes(1024L)) } yield () } ``` -------------------------------- ### Limit and Skip Documents Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/find.md Use `skip` and `limit` methods to control the number of documents returned. `skip` defines how many documents to ignore from the beginning, and `limit` sets the maximum number of documents to retrieve. ```scala val data = IO[Iterable[Document]] = collection.find .skip(10) // skip the first 10 .limit(100) // take the next 100 .all ``` -------------------------------- ### Add ZIO dependency Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/zio.md Include the mongo4cats-zio dependency in your build file. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio" % "" ``` -------------------------------- ### Manage Database Indexes Source: https://context7.com/kirill5k/mongo4cats/llms.txt Covers creating simple, compound, unique, and text indexes, as well as using MongoDB Java driver index builders. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.operations.Index import mongo4cats.models.collection.IndexOptions MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") // Create a simple ascending index indexName1 <- coll.createIndex(Index.ascending("field")) // Create a descending index indexName2 <- coll.createIndex(Index.descending("timestamp")) // Create a compound index compoundIndex = Index.ascending("field1").descending("field2") indexName3 <- coll.createIndex(compoundIndex) // Combine indexes index1 = Index.ascending("field1") index2 = Index.descending("field2") combined = index1.combinedWith(index2) // Create index with options (unique constraint) uniqueIndex = Index.ascending("name", "email") indexName4 <- coll.createIndex(uniqueIndex, IndexOptions().unique(true)) // Create text index for full-text search textIndex <- coll.createIndex(Index.text("content")) // Using MongoDB Java driver builders javaIndex = com.mongodb.client.model.Indexes.compoundIndex( com.mongodb.client.model.Indexes.ascending("field1"), com.mongodb.client.model.Indexes.ascending("field2") ) indexName5 <- coll.createIndex(javaIndex) } yield () } ``` -------------------------------- ### Create an index with options in Scala Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/indexes.md Apply additional configurations like uniqueness by passing an IndexOptions object to the createIndex method. ```scala import mongo4cats.operations.Index import mongo4cats.models.collection.IndexOptions val index = Index.ascending("name", "email") val options = IndexOptions().unique(true) val result: IO[String] = collection.createIndex(index, options) ``` -------------------------------- ### Add ZIO 2 Integration Dependencies Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/index.md Include these dependencies for ZIO 2 integration with mongo4cats. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio" % "" ``` ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-embedded" % "" ``` -------------------------------- ### Create BSON documents Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/documents.md Constructs a new Document using the BsonValue companion object to explicitly define types. ```scala import mongo4cats.bson.{BsonValue, Document, ObjectId} import java.time.Instant val doc: Document = Document( "_id" -> BsonValue.objectId(ObjectId.gen), "null" -> BsonValue.Null, "string" -> BsonValue.string("str"), "int" -> BsonValue.int(1), "boolean" -> BsonValue.boolean(true), "double" -> BsonValue.double(2.0), "int" -> BsonValue.int(1), "long" -> BsonValue.long(1660999000L), "dateTime" -> BsonValue.instant(Instant.now), "array" -> BsonValue.array(BsonValue.string("item1"), BsonValue.string("item2"), BsonValue.string("item3")), "nestedDocument" -> BsonValue.document(Document("field" -> BsonValue.string("nested"))) ) ``` -------------------------------- ### Retrieve distinct values with custom types and codecs Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/distinct.md Shows how to handle complex document types using upcasting or explicit codec providers. ```scala import mongo4cats.bson.Document val distinctValues: IO[Iterable[Document]] = collection.distinct[Document]("field1").all // assuming you have an instance of MongoCodecProvider[MyClass] available in the implicit scope val distinctValues: IO[Iterable[MyClass]] = collection.distinctWithCodec[MyClass]("field1").all // or you can add codecs explicitly val distinctValues: IO[Iterable[MyClass]] = collection.withAddedCodec(myClassCodecs).distinct[MyClass]("field1").all ``` -------------------------------- ### Sort Documents Using Helper Methods Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/find.md Alternatively, use `sortBy` for ascending and `sortByDesc` for descending order. ```scala val data = IO[Iterable[Document]] = collection.find.sortBy("field1").sortByDesc("field2").all ``` -------------------------------- ### Add Mongo4cats dependencies to build.sbt Source: https://github.com/kirill5k/mongo4cats/blob/master/website/src/pages/home.mdx Include these dependencies in your build configuration to use the core library or ZIO-specific modules. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-core" % "" libraryDependencies += "io.github.kirill5k" %% "mongo4cats-embedded" % "" % Test ``` ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio" % "" libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-embedded" % "" % Test ``` -------------------------------- ### Add Mongo4cats Dependencies Source: https://context7.com/kirill5k/mongo4cats/llms.txt Include these dependencies in your build.sbt to enable core functionality, codec derivation, and testing support. ```scala // Core dependency libraryDependencies += "io.github.kirill5k" %% "mongo4cats-core" % "" // Circe integration for automatic codec derivation libraryDependencies += "io.github.kirill5k" %% "mongo4cats-circe" % "" // ZIO Json integration for automatic codec derivation libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-json" % "" // Embedded MongoDB for testing libraryDependencies += "io.github.kirill5k" %% "mongo4cats-embedded" % "" % Test // ZIO 2 integration libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio" % "" libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-embedded" % "" ``` -------------------------------- ### Create a Change Stream with an Aggregation Pipeline Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/watch.md Use this to monitor specific changes in a collection by applying an aggregation pipeline. Ensure the pipeline is correctly defined to filter or transform change events. ```scala import mongo4cats.collection.operations.{Aggregate, Filter} val changes: fs2.Stream[IO, Document] = collection.watch(Aggregate.matchBy(Filter.gte("amount", 100))).stream ``` -------------------------------- ### Create a simple index in Scala Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/indexes.md Use the createIndex method with an ascending index specification to optimize query performance. ```scala import mongo4cats.operations.Index val result: IO[String] = collection.createIndex(Index.ascending("field")) ``` -------------------------------- ### Add mongo4cats-core Dependency Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/index.md Include this dependency in your build.sbt to use the core mongo4cats library. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-core" % "" ``` -------------------------------- ### Add mongo4cats-zio-json Dependency Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/index.md Include this dependency for automatic derivation of Bson codecs using ZIO Json. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-zio-json" % "" ``` -------------------------------- ### Build MongoDB Query Filters in Scala Source: https://context7.com/kirill5k/mongo4cats/llms.txt Illustrates how to construct MongoDB query filters using the `Filter` object for equality, less than, greater than, existence, and regex matching. Shows composition of filters using logical AND (&&) and OR (||) operators for complex queries. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.operations.Filter import mongo4cats.bson.Document import mongo4cats.bson.syntax._ MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) // Basic filters filter1 = Filter.eq("field1", "foo") // field1 == "foo" filter2 = Filter.lt("index", 10) // index < 10 filter3 = Filter.gt("index", 50) // index > 50 filter4 = Filter.exists("field3") // field3 exists filter5 = Filter.regex("name", "doc-[1-9]") // regex match // Composing filters with logical operators combinedFilter = (filter1 || filter2) && Filter.exists("name") // Using filters in queries docs <- coll.find .filter(Filter.lt("index", 10) || Filter.regex("name", "doc-[1-9]0")) .sortByDesc("name") .limit(5) .all _ <- IO.println(docs) } yield () } ``` -------------------------------- ### Add mongo4cats Dependencies (Cats Effect/FS2) Source: https://github.com/kirill5k/mongo4cats/blob/master/readme.md Add these lines to your build.sbt to include the core mongo4cats library and the embedded driver for testing when using Cats Effect and FS2. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-core" % "" libraryDependencies += "io.github.kirill5k" %% "mongo4cats-embedded" % "" % Test ``` -------------------------------- ### Query Documents with Mongo4cats in Scala Source: https://context7.com/kirill5k/mongo4cats/llms.txt Covers various ways to query MongoDB collections using Mongo4cats, including streaming all documents, retrieving the first matching document, fetching all matching documents, and implementing pagination with skip and limit. Demonstrates sorting results in ascending and descending order. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.operations.{Filter, Sort} import mongo4cats.bson.Document MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") // Get all documents as a stream allDocsStream = coll.find.stream // fs2.Stream[IO, Document] // Get first matching document firstDoc <- coll.find(Filter.eq("field1", "foo")).first // IO[Option[Document]] // Get all matching documents as a collection allDocs <- coll.find(Filter.gt("index", 50)).all // IO[Iterable[Document]] // Pagination with skip and limit pagedDocs <- coll.find .skip(10) // skip first 10 documents .limit(100) // take next 100 documents .all // Sorting with Sort builder sortedDocs <- coll.find .sort(Sort.asc("field1").desc("field2")) .all // Or using convenience methods sortedDocs2 <- coll.find .sortBy("field1") .sortByDesc("field2") .all // Complex query with multiple options complexQuery <- coll.find .noCursorTimeout(true) .filter(Filter.lt("index", 10) || Filter.regex("name", "doc-[1-9]0")) .sortByDesc("name") .limit(5) .all } yield () } ``` -------------------------------- ### Retrieve a generic collection Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/collection.md Obtain a MongoCollection instance for BSON Documents from an existing database. ```scala import mongo4cats.bson.Document import mongo4cats.collection.MongoCollection val collection: IO[MongoCollection[IO, Document]] = database.getCollection("mycoll") ``` -------------------------------- ### Create a collection explicitly Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/collection.md Create a new collection in the database, optionally specifying creation options like capped collection settings. ```scala val collection: IO[Unit] = database.createCollection("mycoll") // or with options import mongo4cats.models.database.CreateCollectionOptions val options = CreateCollectionOptions().capped(true).sizeInBytes(1024L) val collection: IO[Unit] = database.createCollection("mycoll", options) ``` -------------------------------- ### Create an index using MongoDB Java builders Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/indexes.md Leverage the standard MongoDB Java library's Index builders for complex index definitions. ```scala import com.mongodb.client.model.Indexes val index = Indexes.compoundIndex(Indexes.ascending("field1"), Indexes.ascending("field2")) val result: IO[String] = collection.createIndex(index) ``` -------------------------------- ### Define an aggregation pipeline Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/operations/aggregate.md Use the Aggregate constructor to define grouping, lookup, and sorting stages for a pipeline. ```scala import mongo4cats.operations.{Accumulator, Aggregate, Sort} // specification for grouping multiple transactions from the same group: val accumulator = Accumulator .sum("count", 1) // number of transactions in a given group .sum("totalAmount", "$amount") // total amount .first("categoryId", "$category._id") // id of a category under which all transactions are grouped val aggregation = Aggregate .group("$category", accumulator) // group all transactions by categoryId and accumulate result into a given specification .lookup("categories", "categoryId", "_id", "category") // find a category for each group of transactions by category id .sort(Sort.desc("totalAmount")) // define the order of the produced results ``` -------------------------------- ### Import Embedded MongoDB Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/zio.md Import the embedded MongoDB module. ```scala import mongo4cats.zio.embedded._ ``` -------------------------------- ### Execute Batch Write Operations Source: https://context7.com/kirill5k/mongo4cats/llms.txt Perform multiple write operations (insert, delete, update, replace) in a single request for efficiency. Supports ordered or unordered execution. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.bson.Document import mongo4cats.bson.syntax._ import mongo4cats.models.collection.{BulkWriteOptions, WriteCommand} import mongo4cats.operations.{Filter, Update} MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") _ <- coll.insertMany((0 to 100).map(i => Document("name" := s"doc-$i", "index" := i))) // Build multiple write commands commands = List( WriteCommand.DeleteOne(Filter.eq("name", "doc-1")), WriteCommand.InsertOne(Document("name" := "doc-101", "index" := 101)), WriteCommand.DeleteMany(Filter.gt("index", 10) && Filter.lt("index", 20)), WriteCommand.UpdateOne(Filter.eq("index", 50), Update.set("name", "doc-50-updated")), WriteCommand.UpdateMany(Filter.gt("index", 90), Update.set("category", "high")), WriteCommand.ReplaceOne(Filter.eq("index", 75), Document("name" := "replaced", "index" := 75)) ) // Execute bulk write with options (unordered for parallel execution) result <- coll.bulkWrite(commands, BulkWriteOptions(ordered = false)) _ <- IO.println(s"Inserted: ${result.getInsertedCount}, Deleted: ${result.getDeletedCount}") } yield () } ``` -------------------------------- ### Add mongo4cats-circe Dependency Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/index.md Add this dependency to enable automatic derivation of Bson codecs via Circe. ```scala libraryDependencies += "io.github.kirill5k" %% "mongo4cats-circe" % "" ``` -------------------------------- ### Update immutable documents Source: https://github.com/kirill5k/mongo4cats/blob/master/website/docs/gettingstarted/documents.md Demonstrates methods to add fields to an existing document, which returns a new immutable instance. ```scala val updatedDoc1 = doc.add("newField" -> BsonValue.string("string")) val updatedDoc2 = doc.add("newField" -> "string") val updatedDoc3 = doc += ("anotherNewField" -> BsonValue.instant(ts)) val updatedDoc4 = doc += ("anotherNewField" := 1) ``` -------------------------------- ### Update Documents with Mongo4cats Source: https://context7.com/kirill5k/mongo4cats/llms.txt Demonstrates single and bulk document updates using the Update builder, including upsert options and direct integration with MongoDB Java driver builders. ```scala import cats.effect.IO import mongo4cats.client.MongoClient import mongo4cats.operations.{Filter, Update} import mongo4cats.models.collection.UpdateOptions import com.mongodb.client.result.UpdateResult MongoClient.fromConnectionString[IO]("mongodb://localhost:27017").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") // Build update operations (chainable) update = Update .set("field1", "foo") .currentDate("lastModified") .inc("counter", 1) .unset("obsoleteField") // Update first matching document result1: UpdateResult <- coll.updateOne(Filter.eq("name", "doc-1"), update) // Update with options (upsert) result2 <- coll.updateOne( Filter.eq("name", "doc-new"), Update.set("field1", "value"), UpdateOptions().upsert(true) ) // Update all matching documents result3 <- coll.updateMany( Filter.lt("index", 10), Update.set("category", "low-index") ) // Using MongoDB Java driver builders directly result4 <- coll.updateOne( com.mongodb.client.model.Filters.empty(), com.mongodb.client.model.Updates.combine( com.mongodb.client.model.Updates.set("field1", "foo"), com.mongodb.client.model.Updates.currentDate("date") ) ) } yield () } ``` -------------------------------- ### Monitor Real-time Collection Changes Source: https://context7.com/kirill5k/mongo4cats/llms.txt Use change streams to monitor inserts, updates, and deletes in real-time. Supports filtering with aggregation pipelines and concurrent operations. ```scala import cats.effect.IO import fs2.Stream import mongo4cats.client.MongoClient import mongo4cats.operations.{Aggregate, Filter} import mongo4cats.bson.Document import mongo4cats.bson.syntax._ MongoClient.fromConnectionString[IO]("mongodb://localhost:27017/?retryWrites=false").use { client => for { db <- client.getDatabase("my-db") coll <- db.getCollection("docs") // Basic change stream - watch all changes watchStream = coll.watch.stream // fs2.Stream[IO, Document] // Watch with filter aggregation pipeline filteredWatch = coll.watch(Aggregate.matchBy(Filter.gte("amount", 100))).stream // Concurrent operations example insertStream = Stream.range(0, 10).evalMap(i => coll.insertOne(Document("name" := s"doc-$i")) ).drain deleteStream = Stream.eval(coll.deleteMany(Filter.empty)).drain dropStream = Stream.eval(coll.drop) opsStream = insertStream ++ deleteStream ++ dropStream // Run watch concurrently with operations updates <- watchStream.concurrently(opsStream).compile.toList _ <- IO.println(updates.mkString("\n")) } yield () } ```