Fork me on GitHub
#xtdb
<
2022-04-29
>
Anthony Bui09:04:19

Hi, been trying to search but is it possible to put a document and not overwrite existing fields? Is this through transaction functions as well?

tatut10:04:51

yes. as patching documents is highly context dependent

3
tatut10:04:05

you should write a tx function that does what is appropriate for your scenario

Anthony Bui10:04:10

gotcha, thanks!

dvingo15:04:29

you can also use :xtdb.api/match for this:

(defn match-update-entity
  "Takes xtdb node, an xt/id and a map. Uses match to merge the new entity with the existing xtdb document atomically.
  Recurs until successful with no limit.

  shout out emccue:
  
  "
  [xtdb-node entity-id new-entity]
  (let [[[old-entity]] (seq (xt/q (xt/db xtdb-node)
                              '{:find  [(pull ?eid [*])]
                                :where [[?eid :xt/id id]]
                                :in    [id]}
                              entity-id))
        new-entity     (merge old-entity new-entity)
        tx             (xt/submit-tx xtdb-node [[::xt/match entity-id old-entity] [::xt/put new-entity]])
        most-recent-tx (xt/await-tx xtdb-node tx)]
    (if (xt/tx-committed? xtdb-node tx)
      most-recent-tx
      (recur xtdb-node entity-id new-entity))))

🥳 1
dvingo15:04:38

new-entity (merge old-entity new-entity) being the relevant part (and ACID guarantees)

🥳 1
richiardiandrea15:08:49

Ran into this and wanted to say thank you, we dropped the merge parte cause it would not work in the case of keys you want to remove (say optional keys that were present but were taken out). The rest looks awesome 😄

richiardiandrea15:08:49

(FWIW for that use case we really like using taoensso.encore/dis-assoc-some)

dvingo16:08:30

thanks! that makes a lot of sense about not using merge

kokonut13:01:21

I have been using merge when I need to update a document, but I am not really familiar with [::xt/match entity-id old-entity]. Can someone let me know what this snippet does here? Or if I just omit it and say the line like (xt/submit-tx xtdb-node [[::xt/put new-entity]]) , what would happen differently?