Giter Site home page Giter Site logo

congomongo's Introduction

CongoMongo ClojarsVersionRelease ClojarsDownloads CircleCI

What?

A toolkit for using MongoDB with Clojure. This library is a pretty lightweight wrapper around the MongoDB Java driver, and can be paired with your favorite framworks or functions for validation such as clojure.spec.alpha.

Supported MongoDB versions

The client was tested with the following MongoDB versions:

  • MongoDB 3.6
  • MongoDB 4.2

Thus, while the library may work just fine with higher MongoDB versions, the full feature support is not guaranteed.

Releases and Dependency Information

Latest stable release is 2.6.0.

Leiningen dependency information:

[congomongo "2.6.0"]

Clojure CLI:

congomongo {:mvn/version "2.6.0"}

Maven dependency information:

<dependency>
  <groupId>congomongo</groupId>
  <artifactId>congomongo</artifactId>
  <version>2.6.0</version>
</dependency>

Gradle dependency information:

compile 'congomongo:congomongo:2.6.0'

Basics

Setup

import

(ns my-mongo-app
  (:require [somnium.congomongo :as m]))

make a connection using array of hosts

(def conn
  (m/make-connection "mydb"
                     :instances [{:host "127.0.0.1" :port 27017}]))
=> #'user/conn

conn => {:mongo #<MongoClient Mongo: /127.0.0.1:20717>, :db #<DBApiLayer mydb>}

or using a mongodb uri

(def conn
  (m/make-connection "mongodb://127.0.0.1/mydb"))
=> #'user/conn

conn => {:mongo #<MongoClient Mongo: /127.0.0.1:20717>, :db #<DBApiLayer mydb>}

set the connection globally

(m/set-connection! conn)

or locally

(m/with-mongo conn
    (m/insert! :robots {:name "robby"}))

close the connection

(m/close-connection conn)

specify a write concern

(m/set-write-concern conn :journaled)

These are the official write concerns, more details about them can be found in the WriteConcern javadoc.

  • :unacknowledged will report network errors - but does not wait for the write to be acknowledged
  • :acknowledged will report key constraint and other errors - this is the default
  • :journaled waits until the primary has sync'd the write to the journal
  • :fsynced waits until a write is sync'd to the filesystem
  • :replica-acknowledged waits until a write is sync'd to at least one replica as well
  • :majority waits until a write is sync'd to a majority of replica nodes

specify a read preference

You can pass a simple read preference (without tags) to each function accepting read preferences. This may look like:

(m/fetch :fruit :read-preference :nearest)

to get the fruit from the nearest server. You may create more advances read preferences using the read-preference function.

(let [p (m/read-preference :nearest {:location "Europe"})]
   (fetch :fruit :read-preference p)
)

to be more specific to get the nearest fruit. You may also set a default ReadPreference on a per collection or connection basis using set-read-preference or set-collection-read-preference!.

(m/set-read-preference conn :primary-preferred)
(m/set-collection-read-preference! :news :secondary)

Simple Tasks


create

(m/insert! :robots
           {:name "robby"})

read

(def my-robot (m/fetch-one :robots)) => #'user/my-robot

my-robot => {:name "robby",
             :_id  #<ObjectId> "0c23396f7e53e34a4c8cf400">}

update

Update query and modifier can use all mongodb operators

(m/update! :robots
  {:_id (:_id my-robot)}
  {:$set {:name "asimo"}})

=>  #<WriteResult { "serverUsed" : "/127.0.0.1:27017" ,
                    "updatedExisting" : true ,
                    "n" : 1 ,
                    "connectionId" : 169 ,
                    "err" :  null  ,
                    "ok" : 1.0}>

destroy

(m/destroy! :robots {:name "asimo"}) => #<WriteResult { "serverUsed" : "/127.0.0.1:27017" ,
                                                        "n" : 1 ,
                                                        "connectionId" : 170 ,
                                                        "err" :  null  ,
                                                        "ok" : 1.0}>
(m/fetch :robots) => ()

More Sophisticated Tasks


mass inserts

(dorun (m/mass-insert!
         :points
         (for [x (range 100) y (range 100)]
           {:x x
            :y y
            :z (* x y)}))

=> nil ;; without dorun this would produce a WriteResult with 10,000 maps in it!

(m/fetch-count :points)
=> 10000

ad-hoc queries

(m/fetch-one
  :points
  :where {:x {:$gt 10
              :$lt 20}
          :y 42
          :z {:$gt 500}})

=> {:x 12, :y 42, :z 504, :_id ... }

aggregation (requires mongodb 2.2 or later)

(m/aggregate
  :expenses
  {:$match {:type "airfare"}}
  {:$project {:department 1, :amount 1}}
  {:$group {:_id "$department", :average {:$avg "$amount"}}})

=> {:serverUsed "...", :result [{:_id ... :average ...} {:_id ... :average ...} ...], :ok 1.0}

This pipeline of operations selects expenses with type = 'airfare', passes just the department and amount fields thru, and groups by department with an average for each.

Based on 10gen's Java Driver example of aggregation.

The aggregate function accepts any number of pipeline operations.

authentication

(m/authenticate conn "myusername" "my password")

=> true

advanced initialization using mongo-options

(m/make-connection :mydb
                   :instances [{:host "127.0.0.1"}]
                   :options (m/mongo-options :auto-connect-retry true))

The available options are hyphen-separated lowercase keyword versions of the camelCase options supported by the Java driver. Prior to CongoMongo 0.4.0, the options matched the fields in the MongoOptions class. As of CongoMongo 0.4.0, the options match the method names in the MongoClientOptions class instead (and an IllegalArgumentException will be thrown if you use an illegal option). The full list (with the 2.10.1 Java driver) is:

(:auto-connect-retry :connect-timeout :connections-per-host :cursor-finalizer-enabled
 :db-decoder-factory :db-encoder-factory :description :legacy-defaults
 :max-auto-connect-retry-time :max-wait-time :read-preference :socket-factory
 :socket-keep-alive :socket-timeout :threads-allowed-to-block-for-connection-multiplier
 :write-concern)

specifying authentication mechanism and source

(m/make-connection :mydb
                   :instances [{:host "127.0.0.1"}]
                   :username "user"
                   :password "password"
                   :auth-source {:mechanism :scram-1 :source "authsourcedb"})

Supported authentication mechanisms:

Key Mechanism
:plain AuthenticationMechanism.PLAIN
:scram-1 AuthenticationMechanism.SCRAM_SHA_1
:scram-256 AuthenticationMechanism.SCRAM_SHA_256

initialization using a Mongo URI

(m/make-connection "mongodb://user:pass@host:27071/databasename")
;; note that authentication is handled when given a user:pass@ section

;; or using SRV DNS service detection
(m/make-connection "mongodb+srv://user:pass@mymongocluster/databasename")

A query string may also be specified containing the options supported by the MongoClientURI class.

easy json

(m/fetch-one :points
             :as :json)

=> "{ \"_id\" : \"0c23396ffe79e34a508cf400\" ,
      \"x\" : 0 , \"y\" : 0 , \"z\" : 0 }"

custom type conversions

For example, use Joda types for dates:

(extend-protocol somnium.congomongo.coerce.ConvertibleFromMongo
  Date
  (mongo->clojure [^java.util.Date d keywordize] (new org.joda.time.DateTime d)))

(extend-protocol somnium.congomongo.coerce.ConvertibleToMongo
  org.joda.time.DateTime
  (clojure->mongo [^org.joda.time.DateTime dt] (.toDate dt)))

explain

Use :explain? on fetch to get performance information about a query. Returns a map of statistics about the query, not rows:

(m/fetch :users :where {:login "alice"} :explain? true)
{:nscannedObjects 2281,
 :nYields 0,
 :nscanned 2281,
 :millis 2,
 :isMultiKey false,
 :cursor "BasicCursor",
 :n 1,
 :indexOnly false,
 :allPlans [{:cursor "BasicCursor", :indexBounds {}}],
 :nChunkSkips 0,
 :indexBounds {},
 :oldPlan {:cursor "BasicCursor", :indexBounds {}}}

default query options

Sometimes it's very helpful to be able to provide default options for all queries (for example, specify default max-time-ms timeout) instead of specifying it for each call. You can do this by wrapping your code in the with-default-query-options macro. Options specified in a particular call will have a priority and overwrite default-query-options.

; This call will only return one item, since it is using the default options
(with-default-query-options {:limit 1}
  (fetch :thingies :where {:foo 1}))

; You can also override the defaults by specifying a new value
(with-default-query-options {:limit 1}
  (fetch :thingies :where {:foo 1} :limit 2)) ; returns 2 items

Developer information

Change Log

Read the change log

Discussions and contributions

There is now a Google Group Come help us make ponies for great good.

Clojars group is congomongo.

License and copyright

Congomongo is made available under the terms of an MIT-style license. Please refer to the source code for the full text of this license and for copyright details.

congomongo's People

Contributors

aboekhoff avatar adamclements avatar amalloy avatar anmonteiro avatar arohner avatar brandonbloom avatar christophermaier avatar circlecai avatar dwwoelfel avatar dyba avatar frozenlock avatar gmvdm avatar gordonsyme avatar gorsuch avatar jaceklaskowski avatar jaor avatar kmagiera avatar licenser avatar marcomorain avatar marksto avatar maxweber avatar mpenet avatar niclasmeier avatar njackson avatar pbiggar avatar purcell avatar raynes avatar scottjad avatar seancorfield avatar smaant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

congomongo's Issues

Java Driver 2.9.2 Update

From the MongoDB mailing list:

"Version 2.9.2 of the MongoDB Java driver has been released. This is a critical update to fix a regression which can cause MongoDB to crash and in some cases cause invalid BSON documents to be inserted. Note that it will not corrupt existing data. See https://jira.mongodb.org/browse/JAVA-660 for details.

If you are running with either 2.9.0 or 2.9.1 in production, please upgrade to this release as soon as possible.

Downloads: http://github.com/mongodb/mongo-java-driver/downloads and http://central.maven.org/maven2/org/mongodb/mongo-java-driver/2.9.2/"

(databases) returns an ArrayList

I just started playing around with Congomongo, and I stumbled over the function (databases).

Why does this function returns an java.util.ArrayList instead of some Clojure-seq? I know I can easily convert it with (seq ...), but I think it should return a Cloure-seq, as we're in a Clojure-environment.

Clojure 1.3

'Also tested with: [org.clojure/clojure "1.3.0"]'

You should use version ranges.

Release snapshot?

Clojars doesn't seem to have a 1st-party congomongo 1.9 snapshot, can you update? Thanks!

format of data returned by (fetch ... :as :json)

Hello,

I'm using (fetch ... :as :json) to try and get query results as json. What it actually returns is a clojure list of individual json strings:

("{...}" "{...}")

rather than a json string of the results, which would look like this:

"[{...},{...}]"

Is there a built-in way to get the result in json? For now I've been using this macro, which seems to do the job, at least when you know you're expecting an array:

(defmacro json-fetch [& args]
  `(str "[" (apply str (interpose "," (fetch ~@args :as :json))) "]"))

Thanks!

Release 0.1.5 to clojars

Could we get release versions into Clojars in addition to snapshots (0.1.5 vs 0.1.5-SNAPSHOT)?

I've got a few libraries that depend on conogomongo, and it would be great if they could depend on releases instead of snapshots.

Thanks, Zack.

Storing things made with defrecord

(defrecord Foo [a b])

(insert! :foos (Foo. 1 2))

throws an error, even though things made with defrecord are essentially maps. Perhaps something to add for the 'new' branch?

clojure->mongo doesn't handle sets correctly

a map whose value is a set of keywords causes org.bson.BasicBSONEncoder to barf with "java.lang.IllegalArgumentException: can't serialize class clojure.lang.Keyword"

If ConvertibleToMongo is extended to java.util.Set with (clojure->mongo [^java.util.Set s] (set (map clojure->mongo s))) it works.

insert! show .throwOnError

Where we don't return the result of calling into the Java driver, we should invoke .throwOnError on the CommandResult object.

Example: unique index and attempt to insert duplicate key. We should have a test for that (first, then fix the bug :)

Missing license

There is no hint under which license congomongo is available. It would be great if you add some license information, so that the people are legally safe if they are using congomongo.

Best regards

Max

writing fetch to disk

unless there is another way (?),
I tried writing a fetch to disk using print-dup:

(defn write-database2 [ file obj]

  (with-open [w (FileWriter. file)]

  (binding [*out* w *print-dup* true] (prn obj))))

but I get this error:

  (write-database2 "f.dat" (fetch :tweets))

  java.lang.IllegalArgumentException: No method in multimethod

'print-dup' for dispatch value: class com.mongodb.ObjectId

Unclear how to use fetch-by-id with auto-generated ObjectIds

It's not clear from the documentation how to use fetch-by-id to get documents by the ObjectIds that Mongo automatically generates.

For example, if you want to use an ObjectId in a URL (e.g., /posts/4f95d3dc30048054ca2bf362), calling fetch-by-id with that ID as the string won't work. You have to create a new ObjectId object by importing org.bson.types.ObjectId and calling (ObjectId. id).

It'd be great to do one of the following: Mention this in the documentation; update the fetch-by-id function to support this; or add a separate function for fetching by these string IDs (e.g. fetch-by-id-str).

We're happy to do any of these, but we're not sure which path is the best to take.

(with @brendannee)

Eagerly loading vectors of db-ref

Hi,

We've been trying to work with a collection where one of the fields is a list of db-ref's to other items from the same collection.

We'd like to be able to eagerly load all of the children elements as we fetch the parent though. So we've looked into using ((with-ref-fetching fetch-by-id) :collection-name (id->object "object-id-as-string")) but to no avail.

Is this use-case supported?

No sorting with fetch-one (or :one? true)

I'm trying to fetch one record with this code:

main=> (fetch "report_ids" :sort {:report_id -1} :one? true)
{:report_id 1, :_id #<ObjectId 4f359c8f0a46e45ae34465dd>}
main=> (fetch "report_ids" :sort {:report_id -1} :limit 1)  
({:report_id 2, :_id #<ObjectId 4f359d6d0a46e45ae34465de>})

And as you can see, if the :one? true option is used, the sorting is ignored. Is this intended or a bug?

Thanks for a great lib!

Why does update! require a document

The default MongoDB update/save functions take a query to find the document to be updated; with upsert enabled, this means that a null return value would be handled for us and an insert would be performed.

In congomongo, it looks like we have to pass in a full document map to update!, which seems to defeat part of the purpose of the update! function altogether, in that a call to fetch-one returns nil if nothing is found.

What's the rationale behind update! semantics?

Reflection warnings

Take another run at removing reflection warnings:

Reflection warning, somnium/congomongo.clj:106 - call to authenticate can't be resolved.
Reflection warning, somnium/congomongo.clj:124 - call to startsWith can't be resolved.
Reflection warning, somnium/congomongo.clj:383 - call to distinct can't be resolved.
Reflection warning, somnium/congomongo.clj:583 - call to createFile can't be resolved.
Reflection warning, somnium/congomongo.clj:627 - call to findOne can't be resolved.
Reflection warning, somnium/congomongo.clj:629 - call to writeTo can't be resolved.
Reflection warning, somnium/congomongo.clj:635 - call to findOne can't be resolved.

You can't sort by multiple fields

When a map is coerced to a DBObject, the order is not preserved which means you can't use :sort {:a 1 :b 1} reliably. You also can't use [{:x 1} {:y 1}] because that doesn't coerce to the correct object.

In general the map -> object coercion doesn't need to maintain order (and it generally can't because Clojure maps are not ordered).

What's needed here is form that takes a sequence of key / value pairs and constructs an in-order DBObject map, which can be used as the argument for :sort (and maybe other things?).

I've started investigating this but I'm not sure yet which way I'll go with the solution - input welcome!

Ugly error when database not connected

I was trying to get things saving to mongo for perhaps a week (a week of spare time, that is). The problem ended up being simply that I hadn't initiated a connection to the database. Instead of getting a descriptive error, I got a NullPointerException. A prettier error would probably save a lot of folks a lot of time.

My error message:

java.lang.NullPointerException
    at somnium.congomongo$insert_BANG_.doInvoke(congomongo.clj:233)
    at clojure.lang.RestFn.invoke(RestFn.java:425)
    at bayou.models.user$insert_BANG_.invoke(user.clj:16)
    at bayou.views.api.user$POSTurl$fn__175.invoke(user.clj:16)
    at bayou.lib.api_helpers$respond.invoke(api_helpers.clj:12)
    at bayou.views.api.user$POSTurl.invoke(user.clj:16)
    at bayou.views.api.user$eval182$fn__183.invoke(user.clj:10)
    at compojure.core$if_route$fn__274.invoke(core.clj:39)
    at compojure.core$if_method$fn__267.invoke(core.clj:24)
    at compojure.core$routing$fn__289.invoke(core.clj:98)
    at clojure.core$some.invoke(core.clj:2388)
    at compojure.core$routing.doInvoke(core.clj:98)
    at clojure.lang.RestFn.applyTo(RestFn.java:139)
    at clojure.core$apply.invoke(core.clj:602)
    at compojure.core$routes$fn__293.invoke(core.clj:103)
    at noir.server.handler$init_routes$fn__1419.invoke(handler.clj:55)
    at noir.request$wrap_request_map$fn__1356.invoke(request.clj:14)
    at ring.middleware.keyword_params$wrap_keyword_params$fn__419.invoke(keyword_params.clj:21)
    at ring.middleware.nested_params$wrap_nested_params$fn__456.invoke(nested_params.clj:64)
    at ring.middleware.params$wrap_params$fn__396.invoke(params.clj:76)
    at ring.middleware.multipart_params$wrap_multipart_params$fn__489.invoke(multipart_params.clj:102)
    at ring.middleware.session$wrap_session$fn__644.invoke(session.clj:40)
    at ring.middleware.cookies$wrap_cookies$fn__581.invoke(cookies.clj:132)
    at noir.server.handler$wrap_base_url$fn__1410.invoke(handler.clj:38)
    at noir.session$noir_session$fn__1370.invoke(session.clj:58)
    at ring.middleware.session$wrap_session$fn__644.invoke(session.clj:40)
    at ring.middleware.cookies$wrap_cookies$fn__581.invoke(cookies.clj:132)
    at noir.cookies$noir_cookies$fn__1222.invoke(cookies.clj:66)
    at ring.middleware.cookies$wrap_cookies$fn__581.invoke(cookies.clj:132)
    at noir.validation$wrap_noir_validation$fn__1397.invoke(validation.clj:88)
    at noir.statuses$wrap_status_pages$fn__1318.invoke(statuses.clj:23)
    at ring.middleware.reload_modified$wrap_reload_modified$fn__781.invoke(reload_modified.clj:15)
    at noir.server.handler$wrap_url_decode$fn__1406.invoke(handler.clj:27)
    at noir.exception$wrap_exceptions$fn__1349.invoke(exception.clj:59)
    at noir.options$wrap_options$fn__1312.invoke(options.clj:34)
    at ring.adapter.jetty$proxy_handler$fn__713.invoke(jetty.clj:16)
    at ring.adapter.jetty.proxy$org.mortbay.jetty.handler.AbstractHandler$0.handle(Unknown Source)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)

Release a non-snapshot version

Versions are being bumped from snapshot to snapshot, could a non-snapshot version be released please?

snapshot versions require lein to check for a new version once a day, which could break code if the snapshot is replaced.

clojure.data.json API change

0.2.0 is a breaking API change: json-str has gone away.

This means projects that use clojure.data.json 0.2.0 will not work with congomongo 0.2.x (because we depend on c.d.j 0.1.x).

If we move to 0.2.0 (which we should - it has a lot of performance improvements), then projects relying on earlier c.d.j builds won't work with that new congomongo build.

newbie problem

I am on a hosted system (dreamhost) I've tested mongodb there and works fine . In congomongo I create the database, which works fine , then when I do this: (insert! :robots {:name "robby"}) , i get com.mongodb.MongoException$Network: can't say something (NO_SOURCE_FILE:0)

Update base Clojure version to 1.4

Since 1.4 is the current stable version - and we've been testing against it for ages - we should change the base dependency from 1.3 to 1.4 and update the multi-version testing to continue testing against 1.3.

No _ns in result

I don't see a _ns key in the results from mongo?

I am using MongoDB 1.8.2 on OSX and I use [congomongo "0.1.5-SNAPSHOT"] in my project.clj.

pre-route patterns

Hi,

I'm not sure if this is an even issue or a missing feature is, but is

(pre-route "/user/:username" {keys: [username]}
...)

supposed to work as expected? when I use this username is nil. I'm using noir 1.2.1

Cheers,
Stefan

1.2 not released?

I have followed the instructions to install Congo Mongo 1.2. However, when I try to install it, I get an error saying:

 [null] An error has occurred while processing the Maven artifact tasks.
 [null]  Diagnosis:
 [null] 
 [null] Unable to resolve artifact: Missing:
 [null] ----------
 [null] 1) org.clojars.somnium:congomongo:jar:0.1.2-SNAPSHOT
 [null] 
 [null]   Try downloading the file manually from the project website.
 [null] 
 [null]   Then, install it using the command: 
 [null]       mvn install:install-file -DgroupId=org.clojars.somnium -DartifactId=congomongo -Dversion=0.1.2-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file
 [null] 
 [null]   Alternatively, if you host your own repository you can deploy the file there: 
 [null]       mvn deploy:deploy-file -DgroupId=org.clojars.somnium -DartifactId=congomongo -Dversion=0.1.2-SNAPSHOT -Dpackaging=jar -Dfile=/path/to/file -Durl=[url] -DrepositoryId=[id]
 [null] 
 [null]   Path to dependency: 
 [null]     1) org.apache.maven:super-pom:jar:2.0
 [null]     2) org.clojars.somnium:congomongo:jar:0.1.2-SNAPSHOT
 [null] 
 [null] ----------
 [null] 1 required artifact is missing.
 [null] 
 [null] for artifact: 
 [null]   org.apache.maven:super-pom:jar:2.0
 [null] 
 [null] from the specified remote repositories:
 [null]   clojars (http://clojars.org/repo/),
 [null]   clojure-snapshots (http://build.clojure.org/snapshots),
 [null]   central (http://repo1.maven.org/maven2)

The order in which sort/limit is processed

Hi,
I just noticed this didn't really work:

(mongo/with-mongo conn
(mongo/fetch :pages
:where {:name name}
:sort {:revision -1}
:limit 1
:one? true))

and I had to use

(mongo/with-mongo conn
(first (mongo/fetch :pages
:where {:name name}
:sort {:revision -1}
:limit 1)))

The first one gave me (incorrectly?):
{ "_id" : ObjectId("4f6606f7e907f549121290b4"), "author" : "asd", "name" : "asd", "body" : "asd", "revision" : 1 }
the second one gave me (correctly?):
{ "_id" : ObjectId("4f660750e907f549121290b5"), "author" : "asd", "name" : "asd", "body" : "asd2", "revision" : 2 }

but in my mongo console, when I do:
db.pages.find({name:"asd"}).sort({revision: -1}).limit(1);
I get the correct one.

My gut feeling tells me that :one? might be called before sorting, but I could be wrong.

can't map file memory - mongo requires 64 bit build for larger datasets

Hi,
I receive this error when trying to add a document from the mongo shell: "can't map file memory - mongo requires 64 bit build for larger datasets". However, when I add the same document from clojure using congomongo, insert! successfully returns and the returned map even contains an :_id key, but when I go to the mongo shell to see if the document has been added, it's not there.

Please tell the user when the db is full and do not silently skip the error.

Thank you very much and keep up the good work =)

Best wishes,
Ricardo

Error running example code

Heya, I'm using clojure 1.1.0 with the latest congomongo from clojars, and can't execute the following example from the README:

(insert! :robots
{:name "robby"})
; Evaluation aborted.

The traceback is pasted below. Is this something that's fixed already in git but not yet pushed to clojars, or do you think there some sort of jar clash going on?

clojure.lang.Keyword cannot be cast to clojure.lang.MapEntry
[Thrown class java.lang.ClassCastException]

Restarts:
0: [ABORT] Return to SLIME's top level.

Backtrace:
0: somnium.congomongo.ClojureDBObject.putClojure(ClojureDBObject.java:35)
1: somnium.congomongo.ClojureDBObject.(ClojureDBObject.java:28)
2: somnium.congomongo.coerce$coerce__6951$fn__6957.invoke(coerce.clj:24)
3: somnium.congomongo.coerce$coerce__6951.doInvoke(coerce.clj:34)
4: clojure.lang.RestFn.invoke(RestFn.java:462)
5: somnium.congomongo$insert_BANG___7014.doInvoke(congomongo.clj:93)
6: clojure.lang.RestFn.invoke(RestFn.java:430)
7: runalytics.playground$eval__7125.invoke(NO_SOURCE_FILE:1)
8: clojure.lang.Compiler.eval(Compiler.java:4642)
9: clojure.core$eval__5236.invoke(core.clj:2017)

add-index! :force option

Is this option still relevant?
https://github.com/aboekhoff/congomongo/blob/d2faa17a447b240fdc75bb8ea1829c610eb1d7e9/src/somnium/congomongo.clj#L451-476

It seems that the last version of the Java driver that supported this option was 1.2 (and CongoMongo is currently using 2.7.3).
https://github.com/mongodb/mongo-java-driver/blob/r1.2/src/main/com/mongodb/DBCollection.java#L181-213

Apparently, in 2.7.3 there's no way to use ensureIndex to force the creation of an index that already exists:
https://github.com/mongodb/mongo-java-driver/blob/r2.7.3/src/main/com/mongodb/DBCollection.java#L495-517

The MongoDB documentation for ensureIndex doesn't currently mention any "force" option either
http://www.mongodb.org/display/DOCS/Indexes#Indexes-CreationOptions

I guess the option was replaced by the reIndex command
http://www.mongodb.org/display/DOCS/Index-Related+Commands#Index-RelatedCommands-ReIndex

So, should the :force references in CongoMongo's add-index! be removed?

Switch to new MongoClient class

Rework connection code to use new MongoClient class.

Document that this changes the write concern default from none to normal (I believe).

Update Mongo driver to 2.9.3

Minor update. Recommended for all users running 2.9.x. Fixes a bug with reads across replica sets before the first write.

0.1.4-SNAPSHOT on Clojars

Are there any plans to put up 0.1.4-SNAPSHOT on Clojars? The README instructions are misleading, as 0.1.3-SNAPSHOT is the most recent jar available for the congomongo group on Clojars at the moment.

Authentication

I've been looking around to find a way to use congomongo to connect to a database that requires authentication. No luck finding help on the web and I can see other people have had the same problem.

After setting up the basic parameters with mongo! the java driver docs shows that you can send an optional
'boolean auth = db.authenticate(username, password)'. Does this require a function in congomongo?

More info: http://www.mongodb.org/display/DOCS/Security+and+Authentication or at https://github.com/mongodb/mongo-java-driver/blob/master/examples/QuickTour.java

Best regards,
Mikkel

Reflection warnings

Probably a good idea to eliminate reflection warnings when running on Clojure 1.3.0?

Here's the list I see locally:

Reflection warning, somnium/congomongo.clj:53 - call to com.mongodb.ServerAddress ctor can't be resolved.
Reflection warning, somnium/congomongo.clj:55 - call to com.mongodb.Mongo ctor can't be resolved.
Reflection warning, somnium/congomongo.clj:56 - call to com.mongodb.Mongo ctor can't be resolved.
Reflection warning, somnium/congomongo.clj:74 - reference to field close can't be resolved.
Reflection warning, somnium/congomongo.clj:134 - call to setWriteConcern can't be resolved.
Reflection warning, somnium/congomongo.clj:138 - call to org.bson.types.ObjectId ctor can't be resolved.
Reflection warning, somnium/congomongo.clj:144 - reference to field toString can't be resolved.
Reflection warning, somnium/congomongo.clj:144 - call to write can't be resolved.
Reflection warning, somnium/congomongo.clj:152 - reference to field getTime can't be resolved.
Reflection warning, somnium/congomongo.clj:231 - call to abs can't be resolved.
Reflection warning, somnium/congomongo.clj:269 - reference to field fetch can't be resolved.
Reflection warning, somnium/congomongo.clj:305 - call to insert can't be resolved.
Reflection warning, somnium/congomongo.clj:306 - call to insert can't be resolved.
Reflection warning, somnium/congomongo.clj:387 - call to ensureIndex can't be resolved.
Reflection warning, somnium/congomongo.clj:402 - call to dropIndex can't be resolved.
Reflection warning, somnium/congomongo.clj:403 - call to dropIndex can't be resolved.
Reflection warning, somnium/congomongo.clj:433 - call to dropDatabase can't be resolved.
Reflection warning, somnium/congomongo.clj:438 - call to getDB can't be resolved.
Reflection warning, somnium/congomongo.clj:446 - reference to field getDatabaseNames can't be resolved.
Reflection warning, somnium/congomongo.clj:478 - call to createFile can't be resolved.
Reflection warning, somnium/congomongo.clj:479 - call to setFilename can't be resolved.
Reflection warning, somnium/congomongo.clj:480 - call to setContentType can't be resolved.
Reflection warning, somnium/congomongo.clj:481 - call to setMetaData can't be resolved.
Reflection warning, somnium/congomongo.clj:482 - reference to field save can't be resolved.
Reflection warning, somnium/congomongo.clj:521 - call to findOne can't be resolved.
Reflection warning, somnium/congomongo.clj:522 - call to writeTo can't be resolved.
Reflection warning, somnium/congomongo.clj:527 - call to findOne can't be resolved.
Reflection warning, somnium/congomongo.clj:528 - reference to field getInputStream can't be resolved.
Reflection warning, somnium/congomongo.clj:538 - call to java.lang.Exception ctor can't be resolved.
Reflection warning, somnium/congomongo.clj:593 - call to mapReduce can't be resolved.
Reflection warning, somnium/congomongo.clj:597 - reference to field results can't be resolved.
Reflection warning, somnium/congomongo.clj:598 - reference to field getOutputCollection can't be resolved.
Reflection warning, somnium/congomongo.clj:598 - reference to field getName can't be resolved.

NPE at driver mongo-java-driver 2.6.3 level (fixed in 2.7.0-pre/master)

Notice branch 2.6.3:

No check for null on _rsStatus
https://github.com/mongodb/mongo-java-driver/blob/r2.6.3/src/main/com/mongodb/DBTCPConnector.java#L287

2.7.0-pre/master:

https://github.com/mongodb/mongo-java-driver/blob/master/src/main/com/mongodb/DBTCPConnector.java#L295
Notice the if check for null.

See below for more detail.

user> (mongo! :db "mydb")
true
user> (insert! :robots {:name "foo"})
; Evaluation aborted.

No message.
[Thrown class java.lang.NullPointerException]

Backtrace:
0: com.mongodb.DBTCPConnector.error(DBTCPConnector.java:287)
1: com.mongodb.DBTCPConnector.say(DBTCPConnector.java:161)
2: com.mongodb.DBTCPConnector.say(DBTCPConnector.java:137)
3: com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:255)
4: com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:210)
5: com.mongodb.DBCollection.insert(DBCollection.java:64)
6: somnium.congomongo$insert_BANG
.doInvoke(congomongo.clj:232)
7: clojure.lang.RestFn.invoke(RestFn.java:425)
8: user$eval2303.invoke(NO_SOURCE_FILE:1)
9: clojure.lang.Compiler.eval(Compiler.java:5424)
10: clojure.lang.Compiler.eval(Compiler.java:5391)
11: clojure.core$eval.invoke(core.clj:2382)
12: swank.commands.basic$eval_region.invoke(basic.clj:47)
13: swank.commands.basic$eval_region.invoke(basic.clj:37)
14: swank.commands.basic$eval814$listener_eval__815.invoke(basic.clj:71)
15: clojure.lang.Var.invoke(Var.java:365)
16: user$eval2301.invoke(NO_SOURCE_FILE)
17: clojure.lang.Compiler.eval(Compiler.java:5424)
18: clojure.lang.Compiler.eval(Compiler.java:5391)
19: clojure.core$eval.invoke(core.clj:2382)
20: swank.core$eval_in_emacs_package.invoke(core.clj:92)
21: swank.core$eval_for_emacs.invoke(core.clj:239)
22: clojure.lang.Var.invoke(Var.java:373)
23: clojure.lang.AFn.applyToHelper(AFn.java:167)
24: clojure.lang.Var.applyTo(Var.java:482)
25: clojure.core$apply.invoke(core.clj:540)
26: swank.core$eval_from_control.invoke(core.clj:99)
27: swank.core$eval_loop.invoke(core.clj:104)
28: swank.core$spawn_repl_thread$fn__499$fn__500.invoke(core.clj:309)
29: clojure.lang.AFn.applyToHelper(AFn.java:159)
30: clojure.lang.AFn.applyTo(AFn.java:151)
31: clojure.core$apply.invoke(core.clj:540)
32: swank.core$spawn_repl_thread$fn__499.doInvoke(core.clj:306)
33: clojure.lang.RestFn.invoke(RestFn.java:397)
34: clojure.lang.AFn.run(AFn.java:24)
35: java.lang.Thread.run(Thread.java:662)

Either add :omit for fields or allow a map

MongoDB lets you specify a map of fields to be returned or omitted. :only currently does coerce-fields which creates a map of fields with all true (1) values. We could either add :omit and extend coerce-fields to take an optional arg to specify the true/false value used or we could extend coerce-fields to accept fields as a map and let users specify {:foo false :bar false} for :only as a way to omit only those fields.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.