amazon-dynamodbdynamoose

dynamoose search using GSI returns Index can't be found for query


Here's my dynamoose schema for table seller

const schema = new dynamoose.Schema({
    PK: {
        type: String,   //ni letak emel.toLowerCase() + #main/business/delivery/ehailing
        hashKey: true,
    },
    SK: {        
        type: String,  
        rangeKey: true,
        "index": {  //utk 'auto' display kedai bila user ada kat location tu
            "name": "SKIndex",
            "global": true,
            "rangeKey": "location"
        }
    },
    "location": String,
}, {
    "saveUnknown": true,
    "timestamps": true
});

As you can see above, I created a GSI with the SK as the hashkey named SKIndex and having location as the rangeKey. So I tried to perform the query below

var SKIndex_search = "some value"
var locality = "some value too"
var filter = new dynamoose.Condition().where("SKIndex").eq(SKIndex_search).filter("location").beginsWith(locality);
var getResult = await Seller.query(filter).exec()

but it will always return the error "InvalidParameter: Index can't be found for query."

============== When running this query Seller.query(SKIndex_search).using("SKIndex").filter("location").beginsWith(locality).exec()

It will display the error message ValidationException: Query condition missed key schema element

Full error log:

aws:dynamodb:describeTable:response - {
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "PK",
                "AttributeType": "S"
            },
            {
                "AttributeName": "SK",
                "AttributeType": "S"
            },
            {
                "AttributeName": "location",
                "AttributeType": "S"
            }
        ],
        "TableName": "earthlings_seller",
        "KeySchema": [
            {
                "AttributeName": "PK",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "SK",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2021-06-26T20:50:13.233Z",
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": "1970-01-01T00:00:00.000Z",
            "LastDecreaseDateTime": "1970-01-01T00:00:00.000Z",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 1,
            "WriteCapacityUnits": 1
        },
        "TableSizeBytes": 312,
        "ItemCount": 1,
        "TableArn": "arn:aws:dynamodb:ddblocal:000000000000:table/earthlings_seller",
        "GlobalSecondaryIndexes": [
            {
                "IndexName": "SKIndex",
                "KeySchema": [
                    {
                        "AttributeName": "SK",
                        "KeyType": "HASH"
                    },
                    {
                        "AttributeName": "location",
                        "KeyType": "RANGE"
                    }
                ],
                "Projection": {
                    "ProjectionType": "ALL"
                },
                "IndexStatus": "ACTIVE",
                "ProvisionedThroughput": {
                    "ReadCapacityUnits": 1,
                    "WriteCapacityUnits": 1
                },
                "IndexSizeBytes": 312,
                "ItemCount": 1,
                "IndexArn": "arn:aws:dynamodb:ddblocal:000000000000:table/earthlings_seller/index/SKIndex"
            }
        ]
    }
}
aws:dynamodb:query:request - {
    "ExpressionAttributeNames": {
        "#qra": "location"
    },
    "ExpressionAttributeValues": {
        ":qrv": {
            "S": "nilai"
        }
    },
    "TableName": "earthlings_seller",
    "IndexName": "SKIndex",
    "KeyConditionExpression": "begins_with (#qra, :qrv)"
}

Solution

  • As descrribed in the Dynamoose documentation, where takes in a key attribute. This key represents an attribute name (SK), not an index name (SKIndex).

    Changing your code to the following should work.

    new dynamoose.Condition().where("SK").eq(SKIndex_search).filter("location").beginsWith(locality);
    

    You can also use the using function to manually set a specific index to run your query on. However this is optional. Dynamoose will use a system to look through your indexes and pick one that best matches your query you are making.