Swiftpack.co -  Package - mongodb/mongo-swift-driver
Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
mongodb/mongo-swift-driver
The official MongoDB driver for Swift
.package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "v1.1.0")

Code Coverage sswg:sandbox|94x20

MongoSwift

The official MongoDB driver for Swift applications on macOS and Linux.

Index

Documentation

The latest documentation for the driver is available here. The latest documentation for the driver's BSON library is available here.

Bugs / Feature Requests

Think you've found a bug? Want to see a new feature in mongo-swift-driver? Please open a case in our issue management tool, JIRA:

  1. Create an account and login: jira.mongodb.org
  2. Navigate to the SWIFT project: jira.mongodb.org/browse/SWIFT
  3. Click Create Issue - Please provide as much information as possible about the issue and how to reproduce it.

Bug reports in JIRA for all driver projects (i.e. NODE, PYTHON, CSHARP, JAVA) and the Core Server (i.e. SERVER) project are public.

Installation

The driver supports use with Swift 5.1+. The minimum macOS version required to build the driver is 10.14. The driver is tested in continuous integration against macOS 10.14, Ubuntu 16.04, and Ubuntu 18.04.

Installation is supported via Swift Package Manager.

Step 1: Install Required System Libraries (Linux Only)

The driver vendors and wraps the MongoDB C driver (libmongoc), which depends on a number of external C libraries when built in Linux environments. As a result, these libraries must be installed on your system in order to build MongoSwift.

To install those libraries, please follow the instructions from libmongoc's documentation.

Step 2: Install the driver

The driver contains two modules to support a variety of use cases: an asynchronous API in MongoSwift, and a synchronous API in MongoSwiftSync. The modules share a number of core types such as options structs. The driver depends on our library swift-bson, containing a BSON implementation. All BSON symbols are re-exported from the drivers' modules, so you do not need to explicitly import BSON in your application.

To install the driver, add the package and relevant module as a dependency in your project's Package.swift file:

// swift-tools-version:5.1
import PackageDescription

let package = Package(
    name: "MyPackage",
    dependencies: [
        .package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "VERSION.STRING.HERE"),
    ],
    targets: [
        // Async module
        .target(name: "MyAsyncTarget", dependencies: ["MongoSwift"]),
        // Sync module
        .target(name: "MySyncTarget", dependencies: ["MongoSwiftSync"])
    ]
)

Then run swift build to download, compile, and link all your dependencies.

Example Usage

Note: You should call cleanupMongoSwift() exactly once at the end of your application to release all memory and other resources allocated by libmongoc.

Connect to MongoDB and Create a Collection

Async:

import MongoSwift
import NIO

let elg = MultiThreadedEventLoopGroup(numberOfThreads: 4)
let client = try MongoClient("mongodb://localhost:27017", using: elg)

defer {
    // clean up driver resources
    try? client.syncClose()
    cleanupMongoSwift()

    // shut down EventLoopGroup
    try? elg.syncShutdownGracefully()
}

let db = client.db("myDB")
let result = db.createCollection("myCollection").flatMap { collection in
    // use collection...
}

Sync:

import MongoSwiftSync

defer {
    // free driver resources
    cleanupMongoSwift()
}

let client = try MongoClient("mongodb://localhost:27017")

let db = client.db("myDB")
let collection = try db.createCollection("myCollection")

// use collection...

Note: we have included the client connectionString parameter for clarity, but if connecting to the default "mongodb://localhost:27017"it may be omitted.

Create and Insert a Document

Async:

let doc: BSONDocument = ["_id": 100, "a": 1, "b": 2, "c": 3]
collection.insertOne(doc).whenSuccess { result in
    print(result?.insertedID ?? "") // prints `.int64(100)`
}

Sync:

let doc: BSONDocument = ["_id": 100, "a": 1, "b": 2, "c": 3]
let result = try collection.insertOne(doc)
print(result?.insertedID ?? "") // prints `.int64(100)`

Find Documents

Async:

let query: BSONDocument = ["a": 1]
// The `sort` option specifies the order in which results are returned
// via the cursor. In this case, `["_id": -1]` indicates that the documents will
// be returned in descending order according to the `_id` field.
let options = FindOptions(sort: ["_id": -1])
let result = collection.find(query, options: options).flatMap { cursor in
    cursor.forEach { doc in
        print(doc)
    }
}

Sync:

let query: BSONDocument = ["a": 1]
// The `sort` option specifies the order in which results are returned
// via the cursor. In this case, `["_id": -1]` indicates that the documents will
// be returned in descending order according to the `_id` field.
let options = FindOptions(sort: ["_id": -1])
let documents = try collection.find(query, options: options)
for d in documents {
    print(try d.get())
}

Work With and Modify Documents

var doc: BSONDocument = ["a": 1, "b": 2, "c": 3]

print(doc) // prints `{"a" : 1, "b" : 2, "c" : 3}`
print(doc["a"] ?? "") // prints `.int64(1)`

// Set a new value
doc["d"] = 4
print(doc) // prints `{"a" : 1, "b" : 2, "c" : 3, "d" : 4}`

// Using functional methods like map, filter:
let evensDoc = doc.filter { elem in
    guard let value = elem.value.asInt() else {
        return false
    }
    return value % 2 == 0
}
print(evensDoc) // prints `{ "b" : 2, "d" : 4 }`

let doubled = doc.map { elem -> Int in
    guard case let value = .int64(value) else {
        return 0
    }

    return Int(value * 2)
}
print(doubled) // prints `[2, 4, 6, 8]`

Note that BSONDocument conforms to Collection, so useful methods from Sequence and Collection are all available. However, runtime guarantees are not yet met for many of these methods.

Usage With Kitura, Vapor, and Perfect

The Examples/ directory contains sample projects that use the driver with Kitura, Vapor, and Perfect.

Please note that the driver is built using SwiftNIO 2, and therefore is incompatible with frameworks built upon SwiftNIO 1. SwiftNIO 2 is used as of Vapor 4.0 and Kitura 2.5.

Development Instructions

See our development guide for instructions for building and testing the driver.

GitHub

link
Stars: 247
Last commit: 3 hours ago

Dependencies

Release Notes

1.1.0
7 weeks ago

The MongoDB Swift driver team is pleased to announce our 1.1.0 release.

Highlights

New BSON Library

Last week, we released version 3.0.0 of SwiftBSON. This is a brand new, pure Swift BSON library. While the internals are all-new, the API is identical to the one that previously lived in the driver with a few additions as described in the release notes, and we've now switched the driver to depend on this library. For convenience, we re-export all symbols from SwiftBSON from MongoSwift and MongoSwiftSync, so you can continue to use BSON types as if they were defined directly in the driver with no breaking changes.

Event Loop "Binding" for Core Async Driver Types

Previously, there was no way to specify at the API level a particular EventLoop that a core driver type (client, database, or collection) should return EventLoopFutures on. We've now introduced a special EventLoopBoundClient type to support this for clients, and added support directly to MongoDatabase and MongoCollection for it as well. Please see our Multithreaded Usage Guide for more details.

Aggregation Improvements

We've added a new helper method to MongoDatabase via SWIFT-577 to support performing database-level aggregations.

We've also added support via SWIFT-506 to both MongoDatabase.aggregate and MongoCollection.aggregate for specifying a Codable type that the returned MongoCursor should decode resulting documents into. Previously, these methods could only return MongoCursor<BSONDocument>s. For example:

/// Collection type.
struct Person: Codable {
    let _id: BSONObjectID
    let name: String
    let age: Int
    let favoriteColor: String
}

let coll = db.collection("people", withType: Person.self)
try coll.insertMany([
    Person(_id: BSONObjectID(),  name: "Kaitlin", age: 26, favoriteColor: "blue")
    Person(_id: BSONObjectID(),  name: "Buffalo", age: 27, favoriteColor: "green")
]).wait()


/// Transformed aggregation output type.
struct PersonOutput: Codable {
    let name: String
    let age: Int
}

let resultsFuture = coll.aggregate([
    ["$project": ["age": 1, "name": 1, "_id": 0]] // only keep the age and name fields
], withOutputType: PersonOutput.self).flatMap { cursor in
    cursor.toArray()
}

// prints [PersonOutput(name: "Kaitlin", age: 26), PersonOutput(name: "Buffalo", age: 27)]
print(try resultsFuture.wait())

MongoClientOptions Improvements

Previously, a number of driver options were only specifiable via connection string, and not supported via MongoClientOptions. We've now added support for specifying a number of options via the options struct as well, such as replicaSet and serverSelectionTimeoutMS.

Included Tickets

Bug

  • [SWIFT-957] - DecodingError when encountering dropDatabase event in change stream
  • [SWIFT-958] - Ensure nil is returned from cursor before returning LogicError
  • [SWIFT-969] - Manually clean up mongoc_uri_t when ConnectionString options validation fails
  • [SWIFT-974] - Cursor gets leaked in findOne after DecodingError
  • [SWIFT-1045] - MongoClient initializer performs blocking DNS lookup

New Feature

  • [SWIFT-481] - Support index all paths
  • [SWIFT-828] - Hidden Indexes
  • [SWIFT-577] - Add database aggregation helper
  • [SWIFT-1028] - Create EventLoopBoundMongoClient type
  • [SWIFT-1029] - Implement EventLoop binding support for database and collection objects
  • [SWIFT-1030] - Implement EventLoop binding support for change streams and cursors
  • [SWIFT-1031] - Implement EventLoop binding support for sessions
  • [SWIFT-459] - Add a renameCollection helper
  • [SWIFT-519] - Support startAfter option for change streams
  • [SWIFT-506] - Allow users to specify the output type of an aggregation

Task

  • [SWIFT-734] - Maintain multiple versions of the documentation
  • [SWIFT-791] - Support shorter SCRAM conversation
  • [SWIFT-854] - Organize API documentation in a more useful way
  • [SWIFT-936] - Update the driver to use the new BSON library
  • [SWIFT-1010] - Test against Swift 5.3 + Linux on Evergreen
  • [SWIFT-1034] - Update readme with how to sort all records after running collection.find()
  • [SWIFT-1092] - Vendor libmongoc 1.17.4
  • [SWIFT-763] - Deprecate geoHaystack and geoSearch

Improvement

  • [SWIFT-805] - Make ExceededTimeLimit retryable writes error
  • [SWIFT-872] - Reduce default keepalive time to align with Azure defaults
  • [SWIFT-903] - Add compressors option to MongoClientOptions
  • [SWIFT-905] - Add heartbeatFrequencyMS option to MongoClientOptions
  • [SWIFT-906] - Add localThresholdMS option to MongoClientOptions
  • [SWIFT-907] - Add serverSelectionTimeoutMS option to MongoClientOptions
  • [SWIFT-909] - Add zLibCompressionLevel option to MongoClientOptions
  • [SWIFT-897] - Add appname option to MongoClientOptions
  • [SWIFT-898] - Add replicaSet option to MongoClientOptions
  • [SWIFT-901] - Add tlsInsecure option to MongoClientOptions
  • [SWIFT-912] - Error if minPoolSize option is provided in connection string
  • [SWIFT-929] - Validate options provided via MongoClientOptions
  • [SWIFT-1015] - Only create monitoring events if the user is actually subscribing to them
  • [SWIFT-1072] - Improve performance of insertion

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco