Node.js에서 Global Secondary Index를 사용하여 특정 조건의 레코드 추출

환경


  • Nodejs
  • AWS Lambda
  • AWS DynamoDB

  • 소개



    DynamoDB에서는 파티션 키 혹은 레인지 키를 사용해서만 기본적으로는 추출을 할 수 있습니다만, 임의의 키를 바탕으로 추출을 실시하고 싶을 때는, Global Secondary Index(이하 GSI)를 사용하는 것으로 임의의 키로 레코드를 추출할 수 있습니다.

    주의점



    다음 사항에 주의해야 합니다.
    * GSI는 1 테이블당 20건까지만 작성할 수 있다
    * GSI의 키로 지정할 수 있는 컬럼의 데이터형은 캐릭터 라인, 수치, 바이너리의 어느 쪽인가일 필요가 있습니다
    * Serverless Framework에서는 아직 거기까지 자유로운 GSI는 작성할 수 없기 때문에 DynamoDB 콘솔에서 GSI를 작성할 필요가 있다

    예를 들어 boolean 형의 컬럼을 키로 GSI는 작성할 수 없습니다 (내가 하려고 하고 있었습니다...)

    참고 정보:
    * DynamoDB의 제한

    전제



    적당합니다만, 다음과 같은 Users 테이블이 있다고 합니다.


    열 이름
    데이터 유형



    username
    문자열
    hash

    age
    integer
    범위

    isPremier
    integer


    isPremier 컬럼은 0 또는 1가 정수로 들어간다고 가정합니다.
    그리고 isPremier0 의 레코드를 전건 취득하고 싶다는 것이 실현하고 싶은 것입니다.

    작동 샘플 절차


  • AWS DynamoDB Console에서 GSI 생성
  • query를 수행하는 Lambda 만들기

  • AWS DynamoDB Console에서 GSI 생성



    AWS DynamoDB Console 페이지 > 테이블 > 인덱스로 이동합니다.

    그리고 インデックスの作成 버튼으로부터 새로운 GSI를 이하와 같이 작성합니다.



    query를 수행하는 Lambda 만들기



    Nodejs에서 Lambda 함수를 만듭니다.
    방금 만든 GSI의 다음 정보를 사용합니다.
    * 테이블 이름: Users* 색인 이름: isPremier-index추출 조건은 isPremier 가 0의 레코드를 전건 취득
    const AWS = require('aws-sdk')
    const DynamoDB = new AWS.DynamoDB.DocumentClient({region: "ap-northeast-1"})
    
    module.exports.hello = async (event, context) => {
      try {
        const params = {
          TableName: 'Users', // テーブル名
          IndexName: 'isPremier-index', // 作成したGSI名
          KeyConditionExpression: '#indexKey = :indexValue', // 条件を指定
          ExpressionAttributeNames : {
            "#indexKey"  : 'isPremier' // GSIの作成時に指定したキー名を設定
          },
          ExpressionAttributeValues: {
            ':indexValue': 0 // isPremierの0を抽出
          }
        }
        let items = [] // 抽出したレコードを格納するための空の配列を定義
    
        const query = async () => {
          console.log('start query')
          let result = await DynamoDB.query(params).promise()
          items.push(...result.Items)
    
          // LastEvaluatedKeyが存在していたら再帰的にqueryを実行
          if(result.LastEvaluatedKey){
            params.ExclusiveStartKey = result.LastEvaluatedKey
            await query()
          }
        }
        await query()
        console.log(`Execution result: ${items.length}`)
      } catch (err) {
        console.error(`[Error]: ${JSON.stringify(err)}`)
        return err
      }
    }
    

    이상으로 조건에 있던 레코드를 전건 취득할 수 있습니다.

    좋은 웹페이지 즐겨찾기