taoensso / faraday

Amazon DynamoDB client for Clojure
https://www.taoensso.com/faraday
Eclipse Public License 1.0
238 stars 84 forks source link

Scan using nested attributes #94

Closed ghost closed 8 years ago

ghost commented 8 years ago

Hi there, firstly thanks for providing this useful clojure library for DynamoDB - I have a question:

Given the following item:

(dyndb/put-item client-opts
                :my-table
                {:id 17 :event-type :points-earned :data {:tx-id "123455"}})

The following scan works as expected and finds the correct item(i.e find all items with event-type == :points-earned):

(dyndb/scan client-opts
            :my-table
            {:attr-conds {:event-type [:eq :points-earned]}})

However, I would like to perform a scan where data.tx-id == "123455" but this query always returns an empty result set - is this possible and how do I specify scanning on a nested attribute(dot notation appears to not work):

;; Always returns [] despite items with data.tx-id == "123455"
(dyndb/scan client-opts
            :my-table
            {:attr-conds {"data.tx-id" [:eq "123455"]}})

Thanks in advance, appreciated any info.

ricardojmendez commented 8 years ago

For nested attributes, you'll need a filter expression. Check out Part 2 of this tutorial. Given your attribute has a dash on the name, you'll need to use expression attribute names as well - you can read more about the reason on the section on projection expressions on the same page.

ghost commented 8 years ago

Thanks for the response - I've tried using a filter expression based on the tutorial with the scan function(the tutorial is using the query function which assumes indexes).

This time is seems to return ALL items despite the filter being provided - am I missing something obvious?

;; Returns all ITEMS(as opposed to only items with data.tx-id = "123455"
(dyndb/scan client-opts
            :my-table
            {:filter-expr "#data.#tx-id = :tx-id"
             :expr-attr-names {"#data" "data"
                               "#tx-id" "tx-id"}
             :expr-attr-vals {":tx-id" "123455"}})
ricardojmendez commented 8 years ago

At first glance that looks OK - which version of the library are you using? Those features made it into 1.9, but weren't there for 1.8.

You can see the tests here.

Side note: you don't need an attribute name for data, actually, just "data.#t" would suffice (with #t defined on :expr-attr-names).

ghost commented 8 years ago

Thanks - I was using 1.8.0, after switching to 1.9.0-beta1 the filters starting working! yay

(let [tx-id "123455"]
  (dyndb/scan client-opts
              :my-table
              {:filter-expr "#data.#tx_id = :tx_id"
               :expr-attr-names {"#data" "data" 
                                 "#tx_id" "tx-id"}
               :expr-attr-vals {":tx_id" tx-id}}))

(Side note: I ended up having to include a data key in :expr-attr-names as when I used data.#tx_id it complained that data is a reserved keyword)

Thanks and much appreciated

ricardojmendez commented 8 years ago

(Side note: I ended up having to include a data key in :expr-attr-names as when I used data.#tx_id it complained that data is a reserved keyword)

Ah, yeah, of course it would be.

Glad you got it working!