Scala For Data Science 책에 소개된 json->객체, 객체 ->json 예제로서 내용이 좋아서 조금 수정해봤다.



Repo.scala


package models


case class Repo(

  val name: String,

  val language: String,

  val size: Long

)




Api.scala

package controllers


import models.Repo

import play.api.libs.json._

import play.api.mvc._


class Api extends Controller {

  implicit val writeRepos = new Writes[Repo] {

    override def writes(repo: Repo) = Json.obj(

      "name" -> repo.name,

      "language" -> repo.language,

      "size" -> repo.size

    )

  }


  val data = List[Repo](

    Repo("backend", "scala", 1),

    Repo("frontend", "jquery", 2)

  )


  def repos(username: String) = Action {

    val repoArray = Json.toJson(data)

    Ok(repoArray)

  }

}



conf/routes 파일에 다음을 추가한다.

GET     /api/repos/:username        controllers.Api.repos(username)



웹 브라우져에서 http://127.0.0.1:9000/api/repos/odersky을 호출한다. 



결과


[{"name":"backend","language":"scala","size":1},{"name":"frontend","language":"jquery","size":2}]




Play 프레임워크에서는 Writes[T] 타입 클래스는 단 하나의 메소드를 가진다.


trait Writes[T] {

  def writes(obj:T):Json

}


Writes 메소드는 Play 프레임워크에 내장되어 있어서 Writes를 직접 구현하지 않아도 된다.


Writes[Repo] 인스턴스는 Api controller 코드에서 정의해서 Api controller 내부에서 사용할 수 있도록 한다. 

Writes[Repo] 타입 클래스는 Repo 인스턴스를 JSON으로 변환하는 방법을 안다. JSON HTTP 응답을 생성하는 방법을 알고 있기 때문에 깔끔한 코드를 짤 수 있다.


자바라면 맵/배열을 이용하거나 custom Serializer 를 사용해야 한다(예, http://www.baeldung.com/jackson-map)


이를 편하게 만들어준다고 할 수 있는 큰 기능인 것 같다.




이제는 json을 객체로 변환하는 코드 테스트이다. 


controllers.Api 클래스의 코드를 다음과 같이 변경한다.




package controllers


import models.Repo

import play.api.mvc._

import play.api.libs.ws.WS

import play.api.Play.current

import play.api.libs.json._

import play.api.libs.functional.syntax._

import play.api.libs.concurrent.Execution.Implicits.defaultContext


class Api extends Controller {

  // Repo -> json

  implicit val writeRepos = new Writes[Repo] {

    override def writes(repo: Repo) = Json.obj(

      "name" -> repo.name,

      "language" -> repo.language,

      "size" -> repo.size

    )

  }


  // json -> Repo

  implicit val default:Reads[Repo] = (

    (JsPath \ "name").read[String] and

      (JsPath \ "language").read[String] and

      (JsPath \ "size").read[Long]

    )(Repo.apply _)


  val data = List[Repo](

    Repo("backend", "scala", 1),

    Repo("frontend", "jquery", 2)

  )


  def repos(username:String) = Action.async {


    val url = s"https://api.github.com/users/$username/repos"

    val response = WS.url(url).get()


    response.map { r =>

      if (r.status == 200) {

        val reposOpt = Json.parse(r.body).validate[List[Repo]]

        reposOpt match {

          case JsSuccess(repos, _) => Ok(Json.toJson(repos))

          case _ => InternalServerError

        }

      }

      else {

        NotFound

      }

    }

  }

}



https://api.github.com/users/odersky/repos의 코드를 실행해 json 파싱하고 Read[Repo]타입 클래스에 저장하도록 한다. 




Posted by '김용환'
,


터미널에서 이미지의 width와 height 얻는 툴은 github에 많다.


https://github.com/scardine/image_size


git clone하고 사용하면 끝이다.


사용법은 너무 간단하다.


$ python get_image_size.py  img.jpg

750 500 27453 JPEG img.jpg

Posted by '김용환'
,


1. OLAP의 cube 개념, Druid소개, 트위터 Algebird 소개 


https://speakerdeck.com/vidma/data-cubing-made-simple-with-spark-algebird-and-hbase


다운로드 자료

https://speakerd.s3.amazonaws.com/presentations/55e816adbba64ab6847c5247a93d4ded/data_cubing_with_hbase.pdf





2. Apache 


우버에서 kappa 아키텍처 오픈소르를 내어놓음.


https://www.slideshare.net/databricks/incremental-processing-on-large-analytical-datasets-with-prasanna-rajaperumal-and-vinoth-chandar


Incremental Processing on Large Analytical Datasets with Prasanna Rajaperumal and Vinoth Chandar from Databricks


오랄리 Strata+hadoop 컨퍼런스에서도 발표했음.

https://conferences.oreilly.com/strata/strata-ca/public/schedule/detail/56511






3. 아파치 키린(apache kyrin)


http://www.zdnet.co.kr/news/news_view.asp?artice_id=20141027110506


아파치 키린 2.0에서 apache spark와 연동할 수 있다. 

Apache Kylin: Speed Up Cubing with Apache Spark with Luke Han and Shaofeng Shi from Databricks





4. OLAP for Big Data, Druid 설명이 잘 나옴.


https://www.slideshare.net/freepsw/olap-for-big-data-druid-vs-apache-kylin-vs-apache-lens

OLAP for Big Data (Druid vs Apache Kylin vs Apache Lens) from SANG WON PARK




Posted by '김용환'
,




축소(shrink) api 예제는 다음과 같다. 



간단한 인덱스를 하나 생성한다.


$ curl -XPUT "http://localhost:9200/source_index"



특정 노드에 shrink를 실행한다. 모든 저장(index.blocks.write)을 막는다.


$ curl -XPUT "http://localhost:9200/source_index/_settings" -d'

{

  "settings": {

    "index.routing.allocation.require._name": "노드 이름", 

    "index.blocks.write": true 

  }

}'





원본 인덱스는 다음 커맨드를 사용해 target_index라는 새로운 인덱스로 축소한다.

$ curl -XPOST 'localhost:9200/source_index/_shrink/target_index?pretty'


모니터링은 _cat/recovery 엔드 포인트를 사용한다.


$ curl -XGET localhost:9200/_cat/recovery


Posted by '김용환'
,



mysql 테이블에서 컬럼을 삭제한다.


alter table `table_name` drop column `old_name`



mysql 테이블에서 컬럼을 변경한다.


alter table `table_name` change `old_name` `new_name` varchar(500) DEFAULT NULL;



mysql 테이블에서 컬럼을 추가한다.



alter table `table_name ` add column `new_name` int(11) default 0;



mysql 테이블에서 여러 컬럼을 추가한다.


alter table `stat_activities` add column actiontags_uv int(11) default 0, add column actiontags_pv int(11) default 0;





mysql과 달리 오라클에서는 테이블 변경을 다음처럼 진행한다.


ALTER TABLE `table_name` RENAME COLUMN `old_name` TO ;



'DB' 카테고리의 다른 글

mysql 완전 삭제  (0) 2017.09.27
mysql 5.7.5에서 크게 바뀐 내용  (0) 2017.09.27
ORDER BY RAND() / 범위 / 범위 미지정 쿼리  (0) 2017.04.13
[derby] validation query  (0) 2017.04.10
[mysql] auto increment 이슈  (0) 2016.12.19
Posted by '김용환'
,


apache common의 UnmodifiableMap은 Immutable과 비슷하지만 기존 맵을 변경하지 못하도록 하지만 실제 객체의 인스턴스를 래핑하는 객체정도로 보면 좋을 것 같다. 


다음은 예시이다. hashCode를 보면 동일한 객체인지 알 수 있다. 





import org.apache.commons.collections.map.UnmodifiableMap;


Map<String, Object> map1 = Maps.newHashMap();

map1.put("key", "value");


MapUtils.debugPrint(System.out, "map1", map1);

System.out.println(map1.hashCode());

System.out.println();


Map<String, Object> map2 = UnmodifiableMap.decorate(map1);

MapUtils.debugPrint(System.out, "map2", map2);

System.out.println(map2.hashCode());



결과


map1 = 

{

    key = value java.lang.String

} java.util.HashMap

112004910


map2 = 

{

    key = value java.lang.String

} org.apache.commons.collections.map.UnmodifiableMap

112004910





UnmodifiableMap 코드 내부에서는 아래와 같이 변경하려 하면 에러를 발생시킨다. 


    public void clear() {

        throw new UnsupportedOperationException();

    }


    public Object put(Object key, Object value) {

        throw new UnsupportedOperationException();

    }


    public void putAll(Map mapToCopy) {

        throw new UnsupportedOperationException();

    }


    public Object remove(Object key) {

        throw new UnsupportedOperationException();

    }


Posted by '김용환'
,

SRE 문화 만들기

scribbling 2017. 6. 14. 17:36


링크드인에서 SRE 문화 만들기에 대한 내용이 있다. 읽어볼 만하다.


https://engineering.linkedin.com/blog/2017/05/building-the-sre-culture-at-linkedin






Posted by '김용환'
,


스팍 2017 발표 자료 올라옴.


https://spark-summit.org/2017/schedule/

'scribbling' 카테고리의 다른 글

[펌] OLAP 빅 데이터 공부자료  (0) 2017.06.20
SRE 문화 만들기  (0) 2017.06.14
[펌] 스파크의 사용 환경 내용 - data bricks  (0) 2017.05.24
[성과] OKR  (0) 2017.05.23
[펌] uber 아키텍처  (0) 2017.05.22
Posted by '김용환'
,



jquery에서는 마침표(.)가 포함된 input name을 그냥 사용하면 문제가 된다.


$('.fortune.content').val()

undefined


역슬래시 두개를 사용해야 한다.



$('.fortune\\.content').val()

"내용나옴"



Posted by '김용환'
,



일래스틱서치 1.x에서 트라이브(tribe) 노드가 소개되었지만, 클러스터와 클러스터를 연결하는 기능으로 애매한 포지션이 있었다..


5.4.0에서 deprecated되고 7.0에서 사라질 예정이라 한다. cross cluster search로 대체될 예정이다.


일래스틱서치에서 애매한 기능은 늘 deprecated된다. 





https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-tribe.html


Tribe nodeedit

Warning

Deprecated in 5.4.0.

The tribe node is deprecated in favour of Cross Cluster Search and will be removed in Elasticsearch 7.0.



corss cluster search 모듈은 다음 내용을 참조한다.

https://www.elastic.co/guide/en/elasticsearch/reference/5.x/modules-cross-cluster-search.html

Posted by '김용환'
,