1.0.0-beta5

This commit is contained in:
Michael S. Klishin 2012-04-29 18:23:28 +04:00
parent b1c6865dcd
commit e6add85795
3 changed files with 24 additions and 268 deletions

View file

@ -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")

286
README.md
View file

@ -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:
<dependency>
<groupId>com.novemberain</groupId>
<artifactId>monger</artifactId>
<version>1.0.0-beta4</version>
<version>1.0.0-beta5</version>
</dependency>
@ -77,81 +68,29 @@ With Maven:
</dependency>
## 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

View file

@ -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"]