dynamoid icon indicating copy to clipboard operation
dynamoid copied to clipboard

How to use condition expressions in a query?

Open nbulaj opened this issue 3 years ago • 6 comments

Hey. I have a question about using Condition expressions with Dynamoid. See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ConditionExpressions.html

I have a users table with name: String and settings: Map attributes. Settings could contain a lot of different nested maps. I need to filter my query and find only users which has color setting in settings map, something like:

FilterExpression = 'attribute_exists(#0.#1)',
ExpressionAttributeNames = {
    "#0": "settings",
    "#1": "color"
},

Is it possible to add such condition to Dynamoid where query on using some plain AWS sdk call? Thanks :bow:

nbulaj avatar Dec 16 '22 10:12 nbulaj

I will check if it's possible to do it with QueryFilter/ScanFilter request parameters (that are deprecated now).

andrykonchin avatar Dec 19 '22 10:12 andrykonchin

Sorry for bothering @andrykonchin , but maybe any update on this? Found filter_expression_convertor (https://github.com/Dynamoid/dynamoid/blob/6d53f100f0478bc04c7c45646771182df603fdc8/lib/dynamoid/adapter_plugin/aws_sdk_v3/filter_expression_convertor.rb#L54 ) don't know if it's possible to reuse it for my case.

nbulaj avatar Nov 28 '23 10:11 nbulaj

It seems QueryFilter/ScanFilter don't support conditions on collections like List and Map:

This parameter does not support attributes of type List or Map. https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html#DDB-Scan-request-ScanFilter https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LegacyConditionalParameters.QueryFilter.html

But recently where was switched from them to the Expressions style, that does support such conditions.

So right now 'settings.color.not_null' => true should not work but it seems easy to support it. Will try to add it soon and release in the next release.

andrykonchin avatar Nov 29 '23 22:11 andrykonchin

Hi @andrykonchin . I see new version is here, I checked https://github.com/Dynamoid/dynamoid/pull/655/files but not sure how correctly to pass params to the .where method to filter by the Map fields which has some key :disappointed: Can you please help with that? Maybe we also need some READE section with how-to section on how to use new expressions

I still see:

field :metadata, :map 

# ...

Model.where("metadata.scores.not_null": true ).count

Traceback (most recent call last):
        1: from (irb):9
Dynamoid::Errors::Error (Unsupported operator screen_scores in metadata.scores.not_null)

nbulaj avatar Feb 26 '24 11:02 nbulaj

OK I see Dynamoid::Criteria::Chain doesn't allow it via def field_condition which does the following:

name, operator = key.to_s.split('.')

So for where("settings.color.not_null": true) it returns => ["metadata", "screen_scores", "not_null"]

nbulaj avatar Feb 26 '24 20:02 nbulaj

The work is in progress (#696) - I will come back to it soon.

andrykonchin avatar Mar 02 '24 16:03 andrykonchin