I've come to learn that Dynamo DB has severe limitations in being able to provide other DB types (SQL, mongo, cassandara, ...) capabilities. Among them is something like in Mongo {attribute: {"$in": [...]}}
or in SQL SELECT ... FROM ... WHERE column IN (...)
. I see that there is a "IN" operator but I am struggling to make a very efficient filter expression of searching to see if a attribute value is present in a given list.
For example, if I have data like:
ID,Attr1,Attr2
1,abc,hi
2,def,hello
3,ghi,howdy
If I have a list to scan the table to find items with Attr2 as any of ["hallo", "hi", "hola", "howdy", "bounjour"]
(with my query it should return item 1 and 3). This list size might not always be this; sometimes there maybe more elements or fewer elements.
I ended up using something like:
filter := expression.Equal(expression.Name("Attr2"), expression.value(myList[0]))
for _, val := range myList[1:] {
filter = filter.Or(expression.Equal(expression.Name("Attr2"), expression.Value(val)))
}
This seems to work but I worry the expression becoming too long and when I print out the expression it looks odd (the OR statements are nested).
{map[filter:((((#0 = :0) OR (#0 = :1)) OR (#0 = :2)) OR (#0 = :3)) OR (#0 = :4) projection:#1, #2, #3, #4, #5, #0, #6] map[#0:0xc0004b06e0 #1:0xc0004b06f0 #2:0xc0004b0700 #3:0xc0004b0710 #4:0xc0004b0720 #5:0xc0004b0730 #6:0xc0004b0740] map[:0:0xc000142500 :1:0xc0001425a0 :2:0xc000142640 :3:0xc0001426e0 :4:0xc000142780]}
I am trying to make it with "IN" condition operator but I can't get it work with a unknown size list. Any advice on making it work with a "IN" operator with a dynamic list to check against? I feel like my Go code might be changed on making it better. I'm bit of a novice in go, any advice? In mongo it was pretty simple to be able to check against a large list. Same with SQL. There doesn't seem to be a proper way in dynamodb as of now (May 2020).
Figured out a way to use the "IN" operator:
wordsToCheck := []string{"hallo", "hi", "hola", "howdy", "bounjour"}
y := []*dynamodb.AttributeValue{}
for _, val := range wordsToCheck {
y = append(y, &dynamodb.AttributeValue{S: aws.String(val)})
}
scanInput := &dynamodb.ScanInput{
TableName: aws.String("mytable"),
ScanFilter: map[string]*dynamodb.Condition{
"Attr2": {
ComparisonOperator: aws.String("IN"),
AttributeValueList: y,
},
},
}
data, err := dynamoclient.Scan(scanInput)
Hope this helps someone! It hasn't been easy to read through the AWS documentation.