ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • DynamoDB Query 공식 문서 파헤치기
    서버/AWS 2020. 3. 4. 23:03

     

     

    DynamoDB Query

     

    모든 DB가 그러하듯, DynamoDB를 사용하는 목적은 결국 쿼리를 하기 위해서이다. 

    이번에는 DynamoDB의 공식 문서를 살펴보면서 Query를 하는 방법을 알아보도록 하자.

     

    앞선 포스팅에서 설명했듯이, DynamoDB와 DynamoDB Document Client가 서로 비슷한 관계에 있고, 다만 Document Client가 JavaScript 개발자에게 좀 더 편한 방식을 제공하기 때문에 이 글에서도 Document Client의 메서드를 통해 설명하도록 하겠다.

     

    먼저 Document Client 클래스의 공식 API 문서의 주소이다. Document Client

    이 중 query 메서드를 클릭해 살펴보도록 하자.

     

    설명이 빈약하니 예제를 통해 살펴보도록 하자.

    DynamoDB의 모든 메서드를 다루는 방식이 그러하듯, 중요한 건 params의 구성이다.

     

    예제 밑에 Calling the query operation을 살펴보도록 하자.

     

    var params = {
      TableName: 'STRING_VALUE', /* required */
      AttributesToGet: [
        'STRING_VALUE',
        /* more items */
      ],
      ConditionalOperator: AND | OR,
      ConsistentRead: true || false,
      ExclusiveStartKey: {
        '<AttributeName>': someValue /* "str" | 10 | true | false | null | [1, "a"] | {a: "b"} */,
        /* '<AttributeName>': ... */
      },
      ExpressionAttributeNames: {
        '<ExpressionAttributeNameVariable>': 'STRING_VALUE',
        /* '<ExpressionAttributeNameVariable>': ... */
      },
      ExpressionAttributeValues: {
        '<ExpressionAttributeValueVariable>': someValue /* "str" | 10 | true | false | null | [1, "a"] | {a: "b"} */,
        /* '<ExpressionAttributeValueVariable>': ... */
      },
      FilterExpression: 'STRING_VALUE',
      IndexName: 'STRING_VALUE',
      KeyConditionExpression: 'STRING_VALUE',
      KeyConditions: {
        '<AttributeName>': {
          ComparisonOperator: EQ | NE | IN | LE | LT | GE | GT | BETWEEN | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH, /* required */
          AttributeValueList: [
            someValue /* "str" | 10 | true | false | null | [1, "a"] | {a: "b"} */,
            /* more items */
          ]
        },
        /* '<AttributeName>': ... */
      },
      Limit: 'NUMBER_VALUE',
      ProjectionExpression: 'STRING_VALUE',
      QueryFilter: {
        '<AttributeName>': {
          ComparisonOperator: EQ | NE | IN | LE | LT | GE | GT | BETWEEN | NOT_NULL | NULL | CONTAINS | NOT_CONTAINS | BEGINS_WITH, /* required */
          AttributeValueList: [
            someValue /* "str" | 10 | true | false | null | [1, "a"] | {a: "b"} */,
            /* more items */
          ]
        },
        /* '<AttributeName>': ... */
      },
      ReturnConsumedCapacity: INDEXES | TOTAL | NONE,
      ScanIndexForward: true || false,
      Select: ALL_ATTRIBUTES | ALL_PROJECTED_ATTRIBUTES | SPECIFIC_ATTRIBUTES | COUNT
    };

     

     

    query를 작성하는 방법에는 크게 두 가지가 있는데, 하나가 표현식을 사용하는 것이고, 나머지는 비표현식을 사용하는 것이다. 위의 opration을 기준으로 예제를 작성하여 이해해보도록 하자.

     


     

    표현식 사용

     

    const params = {
        TableName : "Users",
        KeyConditionExpression : "#user = :user and begins_with(#phone, :phone)",
        ExpressionAttributeNames : {
        	"#user" : "user_id",
            "#phone" : "phoneNumber"
        },
        ExpressionAttributeValues : {
        	":user" : "catnap",
            ":phone" : "010"
        }
    }

     

    • TableName은 쿼리를 할 대상 테이블을 의미한다. 이 부분은 꼭 명시되어야 한다.
    • KeyConditionExpression은 Key(파티션 키와 정렬 키)의 조건 표현식을 의미하는 것으로, 한 문장으로 간단하게 적을 수 있어서 많이 사용한다. 여기서 사용되는 표현식은 DynamoDB 쿼리 작업을 살펴보면 좋다.
    • ExpressionAttributeNames는 Key 속성의 별칭을 만드는 역할을 한다. DB에 파티션 키가 user_id이고, 정렬 키가 phoneNumber라고 하자. 두 속성의 이름이 너무 길기 때문에, 나는 #user와 #phone으로 별칭을 지어줬다. 그렇기 때문에 위의 키 조건 표현식에서 #user와 #phone이 사용된 것을 확인할 수 있다.
    • ExpressionAttributeValues는 속성 값을 할당해주는 역할을 한다. 위의 키 조건 표현식에서 :user와 :phone이 조건 비교 대상인 걸 확인할 수 있는데, 이 두 속성의 값을 각각 "catnap", "010"으로 정한 걸 확인할 수 있다.

    비표현식 사용

    const params = {
        TableName : "Users",
        KeyCondition : {
            'user_id' : {
                ComparisonOperator : "EQ",
                AttributeValueList : ["catnap"]
            },
            'phoneNumber' : {
                ComparisonOperator : "BEGINS_WITH",
                AttributeValueList : ["010"]
            }
        }
    }

     

    위의 표현식과 비교했을 때보단 복잡해 보인다. 하지만!! 이걸 하나하나 뜯어보고 이해하게 된다면, 공식 문서의 도움을 받기는 오히려 쉬울 수도 있다. 

    기본적인 틀은 비슷하다. 다만 KeyCondition이 객체 형식으로 입력이 되어야 한다.

    • ComparisonOperator은 비교 연산 방식을 의미한다. 여기서 EQ는 Equal을 의미하는 데, 자세한 설명은 DynamoDB의 키 조건을 살펴보면 된다.
    • AttributeValueList는 연산 대상이 되는 속성들의 값들의 리스트이다. 위 URL을 통해 들어가 키 조건들을 살펴보면 리스트에 몇 개의 요소가 적혀야 할 지 알 수 있다.

    표현식과 비표현식 두 가지를 살펴 보았다. 위 예제에서는 파티션 키와 정렬 키를 이용한 쿼리만을 살펴보았다(파티션 키만을 사용해서도 쿼리 작성이 가능하다.). 하지만 더 정교한 쿼리를 위해선 다른 속성의 값을 이용해야 한다. 

     

    그 때 사용해야할 건 FilterExpression 혹은 QueryFilter이다. 위의 operation을 살펴보면 이제는 어떻게 작성하는 지 이해가 갈 것이다. 참고로 키 조건의 연산으로는 Exist, Not Exist, Contains와 Not Contains가 사용이 불가능하다. 이러한 연산들은 키가 아닌 속성들에만 사용이 가능하니 스키마 구성을 잘하는 게 중요하겠다!!

    (contains는 어떠한 값이 해당 속성 값에 속해 있는 가를 묻는 연산이고, exists는 해당 속성 값이 존재하는 가를 묻는 연산이다.)

     

     

     

    댓글

Designed by Tistory.