ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MongoDB Time Series Collection - 3
    mongoDB 2022. 3. 25. 19:53

    https://zzihyeon.tistory.com/47

     

    MongoDB Time Series Collection - 2

    MongoDB Time Series Collection - 1 :: 개발 일상 일지 (tistory.com) 에 이어서 작성하도록 하겠다. How to Create?  mongoDB에서 time-series collection을 사용하는 방법은 매우 간단하다. createCollection..

    zzihyeon.tistory.com

    이제 이론을 어느정도 알았으니 실제로 확인해보자

    Create Collection

     이전 포스트에서 방법을 알았으니 실제로 create해보자

    실제로 mongoDB에 createCollection을 한 결과

    성공적으로 collection을 생성했으니 아래의 명령어로 timeseries로 생성되었는지 확인을 해보자

    db.runCommand( { listCollections: 1.0 } )

    type이 timeseries인걸 확인할 수 있다

    expireAfterSeconds 값을 변경하거나 off하고 싶을 수 있다. 그럴 땐 아래와 같이 하면 된다.

    db.runCommand({collMod:"searchHistory",expireAfterSeconds:63072000}); # 시간 변경
    db.runCommand({collMod:"searchHistory",expireAfterSeconds:"off"}); #option 삭제

    granularity 값을 변경하고 싶을 수 있다.(default는 seconds이고 off는 불가능) 이 때는 주의사항이 있는데

    "seconds" -> "minutes" -> "hours" 같이 큰 단위로만 변경할 수 있다. 현재 "minutes"로 설정되어 있는데 seconds, hours로 변경해보겠다. 에러 메세지가 예상과 다르게 뜨긴 하지만 아무튼 "hours"로만 변경 가능한 것을 알 수 있다.

    seconds로 변경은 실패하는 것을 볼 수 있다.

     db.runCommand( { listCollections: 1 } )

    로 확인을 해보면 expireAfterSeconds는 "off"로 제거했기 때문에 사라졌고 granularity가 "hours"로 변경되어 있는 것을 확인할 수 있다.

    Insert Data

     search history에 관한 작업을 개발하기 위해 DB를 공부하는 것이므로 이에 관련된 data로 해보도록 하겠다.

    아래의 data는 임시로 만든 data인데 user가 어떤 user를 조회했는지에 대한 timeseries data이다. metadata에는 조회하는 사용자 정보를 저장하고, target에는 조회 된 사용자 정보를 저장했다. 

    db.searchHistory.insertMany( [
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T00:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T04:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T08:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T12:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T16:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-18T20:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      }, {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T00:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T04:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T08:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T12:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T16:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      },
      {
         "source": { "userId": 1, "type": "user" },
         "ts": ISODate("2021-05-19T20:00:00.000Z"),
         "target": {
           "id":1,
           "name":"zzihyeon",
           "image":"http://image.png"
         }
      }
    ] )

    성공적으로 data가 insert됐다

    Query

     이제 insert한 data를 읽어서 확인해보자

    db.searchHistory.findOne({
       "ts": ISODate("2021-05-18T00:00:00.000Z")
    })

    입력한 데이터를 확인할 수 있다.
    조금 잘렸지만 모든 데이터를 조회했을 때 정상적으로 들어가있음을 볼 수 있다.

    Create Secondary Indexes

     metaField, timeField의 값에만 secondary index를 create할 수 있다.

     어느 유저가 시간 기준으로 어떤 검색을 했는지 알고싶기 때문에 "source.userId"와 "ts"를 key로 index를 생성하도록 하겠다.

     db.searchHistory.createIndex({"source.userId":1, "ts": 1});

    index가 정상적으로 생성됨을 볼 수 있다.

    이제 이 index가 정상적으로 동작하는지 확인해보자. explain의 winningPlan을 보면 어느 index가 적용됐는지 알 수 있다.

    db.searchHistory.find({"source.userId":1}).sort({"ts":1}).explain();

    생성한 index가 적용되었음을 확인할 수 있다.

    Aggregation

     만약 내가 위에 저장한 검색기록을 일별로 나누고 싶다고 가정하면 아래와 같이 aggregation을 작성할 수 있다.

    db.searchHistory.aggregate( [
    	{ 
        	$project: {
            	date:{ 
                	$dateToParts: {date:"$ts"}},
                    user: "$source.userId",
                    target:1,
                    source: 1
                } 
            }, {
            	$group: { 
                	_id: {
                    	date: {
                        	year:"$date.year",
                            month:"$date.month",
                            day:"$date.day"
                        }
                    }, 
                    history:{$push:"$target"}
                }
            }
        ]);

    일자별로 나누어져 history가 배열로 저장된 것을 볼 수 있다.

    결론

     생각보다 기존 collection에 비해 변경된 점도 많지 않고 사용도 간편해서 충분히 사용해볼만한 가치가 있다고 생각한다. 비록 지원하지 않는 기능이 많지만 (물론 앞으로 더 개선되겠지만) mongoDB 하나만으로 대부분의 작업을 하는게 더 편리하다고 생각한다. 이번 기회에 적용해보고 후기를 작성할 예정이다.

     

     추가로 이걸 정리하다가 mongoDB GraphQL API(https://www.mongodb.com/docs/realm/graphql/)를 발견했는데 다음엔 이거에 대해 공부를 해보고자 한다.

    'mongoDB' 카테고리의 다른 글

    MongoDB CRUD - 어떻게 완화된 ACID (BASE) 인가?  (0) 2022.03.28
    Mongodb - database and collection  (0) 2022.03.27
    MongoDB Time Series Collection - 2  (0) 2022.03.25
    MongoDB Time Series Collection - 1  (0) 2022.03.25
    MongoDB란  (2) 2022.03.24

    댓글

Designed by Tistory.