使用DynamoDB本地中的包含查询全局二级索引

时间:2019-04-11 23:59:11

标签: node.js amazon-dynamodb aws-sdk amazon-dynamodb-local

我将id作为表的哈希键,并将returnItemId作为GSI。 returnItemId是一个字符串,其中包含用逗号分隔的值。给定GSI的编号,我希望能够使用contains

来查询并获取包含该编号的正确项目

var params = {
    "AttributeDefinitions": [ // describbes the key schema of the table
    {
      "AttributeName": "id",
      "AttributeType": "S"
    },
    {
      "AttributeName": "returnItemId",
      "AttributeType": "S"
    }
  ],
  // Hash for Primary Table
  "KeySchema": [
    {
      "AttributeName": "id",
      "KeyType": "HASH"
    }
  ],

  "GlobalSecondaryIndexes": [
    {
      "IndexName": "ReturnItemIndex",
      "KeySchema": [
        {
          "AttributeName": "returnItemId", //must match one of attributedefinitions names
          "KeyType": "HASH"
        }
      ],
      "Projection": {
        "ProjectionType": "ALL"
      },
      "ProvisionedThroughput": {
        "ReadCapacityUnits": 5,
        "WriteCapacityUnits": 5
      }
    }
  ],

  "ProvisionedThroughput": {
    "ReadCapacityUnits": 5,
    "WriteCapacityUnits": 5
  },


  "TableName": "my-table"
};
dynamodb.createTable(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response

});

然后我要创建2个项目

var params = {
    TableName: 'my-table',
    Item: { 
    
        "id": "the_first_item",
        "returnItemId": "123,456,789"
    },
};
docClient.put(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

第二项

var params = {
    TableName: 'my-table',
    Item: { 
    
        "id": "the_second_item",
        "returnItemId": "987,654,321"
    },
};
docClient.put(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

这两个项目看起来像enter image description here

我正在尝试运行查询,并使用以下查询获取包含987的正确项目。由于我的第一项包含123,456,789,第二项具有987,654,321,因此此方法应返回第二项。

var params = {
    TableName: 'my-table',
    IndexName: 'ReturnItemIndex', // optional (if querying an index)
    KeyConditionExpression: 'contains(returnItemId, :return_id)',
    //FilterExpression: 'contains(returnItemId, :return_id)', // a string representing a constraint on the attribute
    ExpressionAttributeValues: { ':return_id': '987' },
};
docClient.query(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});

但是在keyconditionexpression中使用contains时出现错误。这种方法可行吗?

1 个答案:

答案 0 :(得分:0)

contains仅可用于过滤器,这意味着:
-查询或扫描操作将遍历所有数据以应用过滤器
-您的读取操作成本将包括所有读取的数据,而不仅仅是匹配的数据
-如果包含“ 12”,那么您也可能会匹配“ 123”和“ 124”
-比起逗号分隔,更好的是使用StringSet或NumberSet数据类型

我会建议其他布局
键区:
分区键:id
排序键:returnItemId
GSI
分区键:returnItemId

数据:

------------------------------------
| id                | returnItemId |
------------------------------------
| "the_first_item"  | "123"        |
| "the_first_item"  | "456"        |
| "the_first_item"  | "789"        |
| "the_second_item" | "987"        |
| "the_second_item" | "654"        |
| "the_second_item" | "321"        |
------------------------------------

然后在GSI中查询关键条件returnItemId = 987(无过滤表达式)