diff --git a/ChangeLog.md b/ChangeLog.md index 4eea7c6..833f625 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -54,7 +54,7 @@ It can be used to connect with or without authentication, for example: (monger.core/connect-via-uri! (System/genenv "MONGOHQ_URL")) ``` -It is also possible to pass connection options and query parameters: +It is also possible to pass connection options as query parameters: ``` clojure (monger.core/connect-via-uri! "mongodb://localhost/test?maxPoolSize=128&waitQueueMultiple=5;waitQueueTimeoutMS=150;socketTimeoutMS=5500&autoConnectRetry=true;safe=false&w=1;wtimeout=2500;fsync=true") diff --git a/README.md b/README.md index fd92d64..1e8071b 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Monger +# Monger, a modern Clojure MongoDB Driver -Monger is an idiomatic Clojure wrapper around MongoDB Java driver. It offers powerful expressive query DSL, strives to support -every MongoDB 2.0+ feature and is well maintained. +Monger is an idiomatic Clojure MongoDB driver for a more civilized age. -[![Continuous Integration status](https://secure.travis-ci.org/michaelklishin/monger.png)](http://travis-ci.org/michaelklishin/monger) +It has batteries included, offers powerful expressive query DSL, strives to support every MongoDB 2.0+ feature and . Monger is built from the +ground up for Clojure 1.3+ and sits on top of the official MongoDB Java driver. ## Project Goals @@ -23,10 +23,6 @@ wanted a client that will * Integrate usage of JavaScript files and ClojureScript (as soon as the compiler gets artifact it is possible to depend on for easy embedding). -## Documentation & Examples - -Please visit our [documentation site](http://clojuremongodb.info/). Our [test suite](https://github.com/michaelklishin/monger/tree/master/test/monger/test) also has many code examples. - ## Community @@ -35,11 +31,6 @@ Please visit our [documentation site](http://clojuremongodb.info/). Our [test su To subscribe for announcements of releases, important changes and so on, please follow [@ClojureWerkz](https://twitter.com/#!/clojurewerkz) on Twitter. -## This is a Work In Progress - -Core Monger APIs are stabilized but it is still a work in progress. Keep that in mind. 1.0 will be released in 2012 -together with documentation guides and dedicated website. - ## Artifacts @@ -47,7 +38,7 @@ together with documentation guides and dedicated website. With Leiningen: - [com.novemberain/monger "1.0.0-beta4"] + [com.novemberain/monger "1.0.0-beta5"] With Maven: @@ -55,7 +46,7 @@ With Maven: com.novemberain monger - 1.0.0-beta4 + 1.0.0-beta5 @@ -77,81 +68,29 @@ With Maven: +## Getting Started + +Please refer to our [Getting Started guide](http://clojuremongodb.info/articles/getting_started.html). Don't hesitate to join our [mailing list](https://groups.google.com/forum/#!forum/clojure-monger) and ask questions, too! + + + + +## Documentation & Examples + +Please visit our [documentation site](http://clojuremongodb.info/). Our [test suite](https://github.com/michaelklishin/monger/tree/master/test/monger/test) also has many code examples. + + + ## Supported Clojure versions Monger is built from the ground up for Clojure 1.3 and up. -## Connecting to MongoDB +## Continuous Integration Status -Monger supports working with multiple connections and/or databases but is optimized for applications that only use one connection -and one database. +[![Continuous Integration status](https://secure.travis-ci.org/michaelklishin/monger.png)](http://travis-ci.org/michaelklishin/monger) -``` clojure -(ns my.service.server - (:require [monger core util])) -;; localhost, default port -(monger.core/connect!) - -;; given host, given port -(monger.core/connect! { :host "db.megacorp.internal" :port 7878 }) -``` - -To set default database Monger will use, use `monger.core/get-db` and `monger.core/set-db!` functions in combination: - -``` clojure -(ns my.service.server - (:require [monger core]])) - -;; localhost, default port -(monger.core/connect!) -(monger.core/set-db! (monger.core/get-db "monger-test")) -``` - -To set default write concern, use `monger.core/set-default-write-concern!` function: - -``` clojure -(monger.core/set-default-write-concern! WriteConcern/FSYNC_SAFE) -``` - -By default Monger will use `WriteConcern/SAFE` as write concern. We believe that MongoDB Java driver (as well as other -official drivers) are using very unsafe defaults when no exceptions are raised, even for network issues. This does not sound -like a good default for most applications: many applications use MongoDB because of the flexibility, not extreme write throughput -requirements. - -## Inserting Documents - -To insert documents, use `monger.collection/insert` and `monger.collection/insert-batch` functions. - -``` clojure -(ns my.service.server - (:use [monger.core :only [connect! connect set-db! get-db]] - [monger.collection :only [insert insert-batch]]) - (:import [org.bson.types ObjectId] - [com.mongodb DB WriteConcern])) - -;; localhost, default port -(connect!) -(set-db! (monger.core/get-db "monger-test")) - -;; without document id -(insert "document" { :first_name "John" :last_name "Lennon" }) - -;; multiple documents at once -(insert-batch "document" [{ :first_name "John" :last_name "Lennon" } - { :first_name "Paul" :last_name "McCartney" }]) - -;; with explicit document id -(insert "documents" { :_id (ObjectId.) :first_name "John" :last_name "Lennon" }) - -;; with a different write concern -(insert "documents" { :_id (ObjectId.) :first_name "John" :last_name "Lennon" } WriteConcern/JOURNAL_SAFE) - -;; with a different database -(let [archive-db (get-db "monger-test.archive")] - (insert archive-db "documents" { :first_name "John" :last_name "Lennon" } WriteConcern/NORMAL)) -``` ### Write Performance @@ -171,189 +110,6 @@ Inserting 100000 documents... With the `SAFE` write concern, it takes roughly 0.5 second to insert 100,000 documents with Clojure 1.3.0. -## Regular Finders - -`monger.collection` namespace provides several finder functions that try to follow MongoDB query language as closely as possible, -even when providing shortcuts for common cases. - -``` clojure -(ns my.service.finders - (:require [monger.collection :as mc]) - (:use [monger.operators])) - -;; find one document by id, as Clojure map -(mc/find-map-by-id "documents" (ObjectId. "4ec2d1a6b55634a935ea4ac8")) - -;; find one document by id, as `com.mongodb.DBObject` instance -(mc/find-by-id "documents" (ObjectId. "4ec2d1a6b55634a935ea4ac8")) - -;; find one document as Clojure map -(mc/find-one-as-map "documents" { :_id (ObjectId. "4ec2d1a6b55634a935ea4ac8") }) - -;; find one document by id, as `com.mongodb.DBObject` instance -(mc/find-one "documents" { :_id (ObjectId. "4ec2d1a6b55634a935ea4ac8") }) - - -;; all documents as Clojure maps -(mc/find-maps "documents") - -;; all documents as `com.mongodb.DBObject` instances -(mc/find "documents") - -;; with a query, as Clojure maps -(mc/find-maps "documents" { :year 1998 }) - -;; with a query, as `com.mongodb.DBObject` instances -(mc/find "documents" { :year 1998 }) - -;; with a query that uses operators -(mc/find "products" { :price_in_subunits { $gt 4000 $lte 1200 } }) - -;; with a query that uses operators as strings -(mc/find "products" { :price_in_subunits { "$gt" 4000 "$lte" 1200 } }) -``` - - -## Powerful Query DSL - -Every application that works with data stores has to query them. As a consequence, having an expressive powerful query DSL is a must -for client libraries like Monger. - -Here is what monger.query DSL feels like: - -``` clojure -(with-collection "movies" - (find { :year { $lt 2010 $gte 2000 }, :revenue { $gt 20000000 } }) - (fields [ :year :title :producer :cast :budget :revenue ]) - (sort { :revenue -1 }) - (skip 10) - (limit 20) - (hint "year-by-year-revenue-idx") - (snapshot)) -``` - -It is easy to add new DSL elements, for example, adding pagination took literally less than 10 lines of Clojure code. Here is what -it looks like: - -``` clojure -(with-collection coll - (find {}) - (paginate :page 1 :per-page 3) - (sort { :title 1 }) - (read-preference ReadPreference/PRIMARY)) -``` - -Query DSL supports composition, too: - -``` clojure -(let - [top3 (partial-query (limit 3)) - by-population-desc (partial-query (sort { :population -1 })) - result (with-collection coll - (find {}) - (merge top3) - (merge by-population-desc))] - ;; ... - ) -``` - -More code examples can be found [in our test suite](https://github.com/michaelklishin/monger/tree/master/test/monger/test). - - -## Updating Documents - -Use `monger.collection/update` and `monger.collection/save`. - - -## Removing Documents - -Use `monger.collection/remove`. - - -## Counting Documents - -Use `monger.collection/count`, `monger.collection/empty?` and `monger.collection/any?`. - - -## Determening Whether Operation Succeeded (or Failed) - -To be documented. - - -## Validators with Validateur - -Monger relies on [Validateur](http://github.com/michaelklishin/validateur) for data validation. - -To be documented. - - -## Integration With Popular Libraries - -Because Monger was built for Clojure 1.3 and later, it can take advantage of relatively new powerful Clojure features such as protocols. - - -### Integration with clojure.data.json - -Monger was created for AMQP and HTTP services that use JSON to serialize message payloads. When serializing documents to JSON, developers -usually want to represent `com.mongodb.ObjectId` instances as strings in resulting JSON documents. Monger integrates with [clojure.data.json](http://github.com/clojure/data.json) to -make that effortless. - -Just load `monger.json` namespace and it will extend `clojure.data.json/WriteJSON` protocol to support `com.mongodb.ObjectId` instance. Then -functions like `clojure.data.json/write-json` will be able to serialize object ids as strings exactly the way you expect it to be. - -``` clojure -(ns my.service.handlers - ;; Make clojure.data.json aware of ObjectId instances - (:require [monger.json])) -``` - - -### Integration with Joda Time - -Monger provides the `monger.joda-time` namespace that extend its own Clojure-to-DBObject conversion protocols as well as -[clojure.data.json](http://github.com/clojure/data.json) `WriteJSON` protocol to handle `org.joda.time.DateTime` instances. To use it, make sure that -you have JodaTime and clojure.data.json on your dependencies list then load `monger.joda-time` like so - -``` clojure -(ns my.service.handlers - ;; Make Monger conversion protocols and clojure.data.json aware of JodaTime's DateTime instances - (:require [monger.joda-time])) -``` - -Now `clojure.data.json/write-json` and related functions will serialize JodaTime date time objects using [ISO8601 date time format](http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html). In addition, functions that convert MongoDB documents to -Clojure maps will instantiate JodaTime date time objects from `java.util.Date` instances MongoDB Java driver uses. - - - -## Factories/Fixtures DSL (For Unit Testing) - -To be documented. - - -## Map/Reduce. Using JavaScript Resources. - -To be documented. - - -## Operations On Indexes - -To be documented. - - -## Database Commands - -To be documented. - - -## GridFS Support - -To be documented. - - -## Helper Functions - -To be documented. - ## Monger Is a ClojureWerkz Project diff --git a/project.clj b/project.clj index 2e5d326..9451235 100644 --- a/project.clj +++ b/project.clj @@ -1,5 +1,5 @@ -(defproject com.novemberain/monger "1.0.0-SNAPSHOT" - :description "Monger is an experimental idiomatic Clojure wrapper around MongoDB Java driver" +(defproject com.novemberain/monger "1.0.0-beta5" + :description "Monger is a Clojure MongoDB client for a more civilized age: friendly, flexible and with batteries included" :min-lein-version "2.0.0" :license {:name "Eclipse Public License"} :dependencies [[org.clojure/clojure "1.3.0"]