简体   繁体   中英

Dynamo = How to use LSI which has multiple # in it with DynamoDb.query using aws-sdk?

I am trying to query Dynamo using aws-sdk . I can query the with Partition Key with but when I try to add LSI, I am getting ValidationException: Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: begins_with, operand type: M ValidationException: Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: begins_with, operand type: M error and not sure how to fix it.

Option-1: This works

const res = await DynamoDb.query({
        TableName: tableName,

        ExclusiveStartKey: lastEvaluatedKey,
        KeyConditionExpression: 'tenantId = :tenantId',
        ExpressionAttributeValues: {
            ':tenantId': tenantId
        }
    }).promise();

Option-2: Not sure what am I missing here.

const res = await DynamoDb.query({
        TableName: tableName,
        IndexName: 'index_channelOrderCreated_id_status',
        ExclusiveStartKey: lastEvaluatedKey,
        KeyConditionExpression: '#tenantId = :tenantId And begins_with(#orderCreatedDate, :orderCreatedDate)',
        ExpressionAttributeValues: {
            ":tenantId": {
                "S": tenantId
            },
            ":orderCreatedDate": {
                "S": beginsWith
            }
        },
        ExpressionAttributeNames: {
            "#tenantId": "tenantId",
            "#orderCreatedDate": "channelOrderCreated#id#status"
        }
    }).promise();

Error:

ValidationException: Invalid KeyConditionExpression: Incorrect operand type for operator or function; operator or function: begins_with, operand type: M

Table Structure: 在此处输入图像描述

Dynamo DB isn't very smart, you need to pass in the IndexName: 'STRING_VALUE', property to tell it you want to use an LSI or GSI index.

SDK docs here

Does your index have the same keys as the table? There's no need for the index in that case.

I suspect the problem is your use of ExclusiveStartKey: lastEvaluatedKey

You don't want to include that in the initial call, only in subsequent calls; assuming you need more than one call to return all the data. DDB will only read 1MB of data at a time.

This was resolved by following change:

const res = await DynamoDb.query({
        TableName: tableName,
        IndexName: 'index_channelOrderCreated_id_status',
        ExclusiveStartKey: lastEvaluatedKey,
        KeyConditionExpression:
            '#tenantId = :tenantId And begins_with(#orderCreatedDate, :orderCreatedDate)',
        ExpressionAttributeValues: {
            ":tenantId": tenantId,
            ":orderCreatedDate": beginsWith,
        },
        ExpressionAttributeNames: {
            "#tenantId": "tenantId",
            "#orderCreatedDate": "channelOrderCreated#id#status"
        }
    }).promise();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM