5

In Monger there is a insert-and-return function for returning a newly inserted document.

There is no update-and-return function.

How can I return an updated document from the function that executes the update?

I think I could use save-and-return but it seems to me that I am not able to use operators like $push with this function.

tobiasbayer
  • 10,269
  • 4
  • 46
  • 64

2 Answers2

4

This is the purpose of Monger's find-and-modify function.

;; Atomically find the doc with a language of "Python", set it to "Clojure", and
;; return the updated doc.
(mgcol/find-and-modify collection 
  {:language "Python"} 
  {:$set {:language "Clojure"} }
  :return-new true)
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • Thanks. I accepted Leonid's answer because he has the lower reputation and he will benefit more of the bounty. As I cannot accept both answers I at least upvoted yours. Hope that's ok for you. – tobiasbayer Jan 17 '13 at 15:29
  • @CodeBrickie I can't say I agree since Leonid basically copied my answer, but as Obiwan said: "You must do what you feel is right, of course." – JohnnyHK Jan 17 '13 at 16:15
  • He copied yours and added a second option. So he produced substantial value as well. – tobiasbayer Jan 18 '13 at 07:19
2

I can see two options for you.

First option is to use JohnnyHK's solution with find-and-modify function:

(mc/find-and-modify "users"
  (select-keys my-doc [:_id])
  { $push { :awards { :award "IBM Fellow"
                      :year  1963
                      :by    "IBM" }}}
  :return-new true)

Second option is to use save instead of update. It's a good choice if you already have the entire document loaded from mongodb. You can easily replace mongodb operators like $push with clojure functions like update-in. Manipulation with clojure maps seems for me as better approach. If you have problems with finding clojure alternatives for mongodb operators I can help you.

For my previous example it will look like this:

(mc/save-and-return "users"
  (update-in my-doc [:awards] conj
    { :award "IBM Fellow"
      :year  1963
      :by    "IBM" }))

Myself, I prefer this way, because it looks more Clojure-ish.

Community
  • 1
  • 1
Leonid Beschastny
  • 50,364
  • 10
  • 118
  • 122