Cloudant DB를 이용한 Watson IoT platform Historical Data 관리

1. Cloudant 이해하기
2. Design document를 응용한 CSV export
3. Watson IoT platform 과 Cloudant 연동하기

 

총 3개의 과정으로 이루어진 실습의 첫번째, Cloudant에 대해 알아 보겠습니다.

[Cloudant 이해하기]

Cloudant DB는 Apache 재단 의 opensource project인 CouchDB를 base로 만들어진 IBM document base No-sql db 입니다.
IBM Cloud PaaS 에서도 제공되고 , Local 설치도 가능 합니다.

<Local version 정보 >
<IBM Cloud PaaS version 정보>

local version은 license를 구매해야 하고, cloud PaaS version은 사용량에 따라 비용을 냅니다.

예를들면 lookup request 1000번은 XXX원 이런 식입니다.
무료로 어느정도까지는 이용가능 하니 실습을 하기에 충분 합니다.
본 실습에서는 cloud version을 이용해보겠습니다.
<자세한 pricing 정보>

위에서 cloudant 를 document base db 라 표현 하였는데,여기서 의미하는 document가 ms word, excel 같은 file을 말하는게 아니라 json, xml,yaml 과 같이 구조화된 데이터 타입을 말합니다.
RDB에서는 너무나 당연하게 사용하던, order by, join, group by, range search, index 등을 no sql은 지원하지 않습니다. RDB 와 조금 다른 형태라서 처음에 사용이 좀 어색할 수 있습니다.
하지만 대용량 비관계형 data를 다루는데 적합한 db이니 잘 활용하면 훌륭한 performance를 경험 할 수 있습니다.

매우 큰 장점 중 하나는 http 방식의 rest api를 제공한다는 것입니다.
고성능을 요하는 enterprise에선 rest 방식이 부적절 할 수 있지만 일반적인 중 소 규모의 transaction에는 개발에 용이하고 편합니다. WEB 과 Mobile transaction에 적합하다고 설명 하고 있습니다.
요즘 대부분의 application client를 rest api형태로 개발하는 것을 감안하면 rest api서버를 따로 운영하지 않아도 되는 부분은 큰 장점 입니다..

[Cloudant access 하기]

Cloudant 에 request를 하는 방식은 대표적으로 http 방식 과 Client library(java,node.js,python) 를 사용하는 방법이 있습니다. http 방식을 이용하면 환경에 영향을 받지 않고 모든 platform과 모든 language에서 사용 가능 합니다.
본 실습에서는 http 방식을 사용하도록 하겠습니다.

기본 모양:

curl https://$USERNAME:$PASSWORD@$ACCOUNT.cloudant.com/query-demo

database 생성:

curl https://$ACCOUNT.cloudant.com/query-demo -X PUT

doc 생성:

curl https://$ACCOUNT.cloudant.com/query-demo/ -X POST -H “Content-Type: application/json” -d  { “_id”: “doc1”, “firstname”: “Sally”, “lastname”: “Brown”, “age”: 16, “location”: “New York City, NY”}

여기서 doc 이라 함은 rdb에서 row 로 보면 됩니다. data 하나의 묶음 입니다. json 형태를 취하고 있습니다.

bulk 로 doc 생성:

curl https://$ACCOUNT.cloudant.com/query-demo/_bulk_docs -X POST -H “Content-Type: application/json” -d @bulkcreate.dat

json 형태의 doc 을 file로 저장한 뒤 이를 읽어와 여러개의 doc을 한번에 생성할 수 있습니다.

[Cloudant View 이해하기]

Cloudant를 잘 활용하기 위해서는 View를 잘 활용해야 합니다. View는 RDB에서의 view와 비슷한 개념을 갖고 있습니다. 사전에 정의된 query를 db에 저장해 두고 이에 대한 결과를 제공 합니다.
실제 data를 읽어와서 정의된 규칙에 따라 result set을 만들어 return 합니다.
cloudant view는 map-reduce방식으로 동작 합니다.

map 이란 key, value로 data를 mapping하는 것을 말합니다.
아래 이미지에서 보는 바와 같이 5개의 doc 이 있고 map function을 통해 make 값을 key 로 하고 value가 1인 map result 가 만들어 집니다.

<이미지 출처: http://yougome.tistory.com/m/392?category=510501>

map function 인 emit의 첫번째 parameter (key 가 되는 field) 는 indexing 되는 field 입니다.
사용자는 해당 key값을 이용하여 query 할 수 있고, key 값을 기준으로 ordering 됩니다.
complex 값으로 sorting을 하고 싶으면 key를 multi로 주면 됩니다. ex)[year, month, day]

reduce란 map된 결과를 갖고 group by 하여 값을 도출해 내는 것입니다.

<이미지 출처: http://yougome.tistory.com/m/392?category=510501>

reduce function은 3개의 parameter를 받습니다.
function (keys, values, rereduce) {
return sum(values);
}

만약 세번째 parameter인 rereduce가 false이면 , keys는 [key,id] 형태의 array가 되고 여기서 key 값은 map function에서 사용된 key 가 됩니다. id는 해당 key 의 document id 값입니다.
values는 keys에 대해 생성된 값의 array가 됩니다.
ex) reduce([ [key1,id1], [key2,id2], [key3,id3] ], [value1,value2,value3], false)

rereduce가 true이면 keys 는 null 이고 values는 reduce funtion의 이전 call로 부터 return 된 값입니다.
ex) reduce(null, [intermediate1,intermediate2,intermediate3], true)

 

built-in reduce function으로 _count, _stats, _sum 이 있습니다.

 

view를 생성하는 방법은 document를 생성하는 방식과 동일 합니다. 다만 view는 design document로 분리 되므로 endpoint가 조금 다릅니다.

curl -X PUT https://$ACCOUNT:$PASSWORD@$ACCOUNT.cloudant.com/$DATABASE/_design/training
–data-binary @view.def

view.def 파일에 view 의 function code가 정의되면 됩니다. (확장자가 꼭 def일 필요는 없습니다.)
training이라는 design document가 생성 될 것이고 그 안에 view가 정의 될 것입니다.

 

[Cloudant Design Document 이해하기]

Design document는 cloudant에서 view, index 등을 정의하는 문서 입니다. json type으로 정의 됩니다.

Cloudant를 제대로 활용하기 위해서는 design document를 명확히 알아야 합니다. 조금 복잡하지만 꼭 이해하고 넘어가세요.
Design document의 구조는 아래와 같습니다.

  • _id: Design Document ID
  • _rev: Design Document Revision
  • views (optional): MapReduce 수행하는
    • viewname : View 이름, 이를 통해 view에 접근 합니다..
      • map: Map Function 정의 .
      • reduce (optional): Reduce Function 정의.
    • indexes (optional): search indexes. 검색을 위해 사용되는 secondary index,
      • index name: Index 이름.
        • analyzer: text로 부터 index term을 어떻게 가져올지 define하는 역할:
          • name: analyzer를 선택 합니다. (standard, email, keyword, simple, whitespace, classic, perfield) 등을 선택 할 수 있습니다.
          • stopwords (optional): index되지 않길 원하는 단어를 지정합니다. 지정하지 않으면 default로 지정되어 있는 값들이 사용 됩니다. [a, an, and, are, as, at, be, but, by, for, if, in, into, is, it, no, not, of, on, or, such, that, the, their, then, there, these, they, this, to, was, will] with]
          • default (for the per field analyzer): fields 에 언어가 특정되지 않을경우 사용될 default 언어.
          • fields (for the per field analyzer): index될 field의 언어를 지정 합니다.
        • index: index 를 handling 하는 Function 정의
      • shows (optional): Show function은 document의 형태를 정의합니다.
        • function name: Function definition.
      • lists (optional): List functions 은 show function과 역할은 같은데, view function의 결과에 대해 format을 지정합니다.
        • function name: Function definition

이해를 돕기 위해 실제로 사용하는 design document format을 첨부 합니다. 각각의 function 부분은 복잡해서 다 표현하지 못했습니다. 이후 과정에서 전체 code를 볼 기회가 있으니 그때 자세히 알아 보겠습니다.

design document json format 참고:

{
  "_id": "_design/iotp",
  "_rev": "4-bbf25a2e6be349cebf337e3adbb8af12",
  "language": "javascript",
  "views": {
    "by-deviceId": {
      "map":"function(doc){\n
               if(doc.deviceId && doc.timestamp){\n
                  emit([doc.deviceId,doc.timestamp],doc);\n}\n}\n"
    }
  },
  "lists": {
    "csv": "function(head,req) {\n ......\n};\n"
  },
  "indexes": {
    "search": {
      "analyzer": "keyword",
      "index": "function(doc) {\n  .......\n  }\n}"
    }
  }
}

토론 참가

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.