Reputation: 200
I write in Ruby On Jets
and use Dynomite to work with DynamoDB. And I have a problem with GSI.
I have a table that has 3 fields: display, value, title_hilight
. I need to use search across all three fields. For this, I decided to use the global secondary index. For testing purposes, I decided to add GSI for the "display" field.
I created migration
class SomeTableMigration<Dynomite::Migration
def up
create_table 'table-name' do | t |
t.partition_key "id: string: hash" # required
t.gsi do | i |
i.partition_key "display: string"
end
end
end
end
Then I created a model
require "active_model"
class ModelName<ApplicationItem
self.set_table_name 'some-model-name'
column :id, :display,:val, :title_hilight
end
Now I'm trying to find a record by value from the "display" field:
ModelName.where ({display: 'asd'})
and I'm getting that error:
Aws::DynamoDB::Errors::ValidationException (Query condition missed key schema element)
Here is the output of aws dynamodb describe-table --table-name table-name --endpoint-url http://localhost:8000
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
},
{
"AttributeName": "display",
"AttributeType": "S"
}
],
"TableName": "some-table-name",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": "2020-10-26T14:52:59.589000+03:00",
"ProvisionedThroughput": {
"LastIncreaseDateTime": "1970-01-01T03:00:00+03:00",
"LastDecreaseDateTime": "1970-01-01T03:00:00+03:00",
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"TableSizeBytes": 112,
"ItemCount": 1,
"TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/some-table-name",
"GlobalSecondaryIndexes": [
{
"IndexName": "display-index",
"KeySchema": [
{
"AttributeName": "display",
"KeyType": "HASH"
}
],
"Projection": {
"ProjectionType": "ALL"
},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"IndexSizeBytes": 112,
"ItemCount": 1,
"IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/some-table-name/index/display-index"
}
]
}
}
I changed the name of the real table to SomeTableName (sometimes just table-name). The rest of the code remained unchanged. Thanks for help
Upvotes: 0
Views: 813
Reputation: 8057
As mentioned here:
In DynamoDB, you can optionally create one or more secondary indexes on a table and query those indexes in the same way that you query a table.
You need to specify GSI name explicitly in your query.
Upvotes: 1
Reputation: 200
@jny answer is correct. He told me to use a different index. I don’t know how to use a different model (see comments on his answer), but the idea with an index is very, very correct. This is how everything works for me now
ModelName.query(
index_name: 'display-index',
expression_attribute_names: { "#display_name" => "display" },
expression_attribute_values: { ":display_value" => "das" },
key_condition_expression: "#display_name = :display_value",
)
Upvotes: 1