요즘 들어 문득 생각이 난다.

처음 결혼했을 때, 아내가 첫째를 임신한 것을 알았을 때, 첫째가 태어났을 때,
둘째를 임신했을 때, 둘째가 태어났을 때......

결혼 후 신혼 생활과 큰 아이가 커가는 모습을 보며 즐거웠던 기억들,
둘째 아이가 태어나 아이들 두 명이 자라는 모습을 보며 기뻐했던 순간들...

그런데 문득 떠오른 생각 하나가 있다.
예전 싸이월드가 한참 유행일 때, 싸이월드에서 육아일기를 남기기 시작했다.
그러다가 페이퍼라는 서비스가 처음 시작되었을 때,
비장한(?) 마음으로 아주 장황한 육아일기 한편을 페이퍼에 연재했다.

까맣게 잊고 있다가 개인 홈페이지를 개설하고도 한참 후에 육아일기를 옮겨야겠다고 생각하고
그동안 방치했던 싸이월드를 뒤지기 시작했다.
그런데 아뿔싸. 페이퍼 서비스가 종료되어 페이퍼에 연재했던 장황한 육아일기는 찾을 길이 없었다.

기억을 더듬어 언젠가 써야지 하면서
이제까지 바쁜 일정에 잊고 있다가 거의 5~6년이 지나서야
그때 그 사건에 해당하는 잊혀져버린 글을 올리는 것 같다.

때는 첫째 예람이가 태어난지 어언..... 잘 기억 안 난다.
하여튼 예람이가 기저귀를 차고,
내가 리얼게인이라는 회사에 팀장으로 근무할 때니 대충 2007년이거나 2008년도였던 거 같다.

그때는 예람이가 2006년 12월 생이니 2~3살 경이었을까?
당시에는 바쁜 일 때문에 보라매 공원 근처에 있던 회사에서
부천 범박동에 있던 집까지 거의 매일 늦은 시간에 퇴근하기 일쑤였다.

그런데 무엇보다도 고통스러웠던 때는,
아내는 피곤해서 잠을 자고, 아들 녀석은 잠이 별로 없어서 내가 안고 재워야할 때였다.
그냥 잠만 안 자면 좋은데, 왜! 왜! 왜! 안고 재울 때 꼭 똥을 싸냐고!!!

비록 기저귀를 차고 있었지만, 우리 아들 똥 냄새. 장난 아니다.
나이가 10살인 지금은 더 심하지만, 두어살 밖에 안 먹었을 때도 똥냄새는 발군이었다.
기저귀를 열고, 물티슈로 엉덩이를 닦을 때면.... 그냥 숨을 참았다. 다 닦을 때까지.
닦다가 조준을 잘못해서 손에 묻을 때는 정말.... 제길. 지금도 울고 싶다.
이순신 장군께서는 나의 죽음을 알리지 말라고 하셨지만, 정말 그때의 내 심정은 누구에게라도 말하고 싶었다.
우리 아들 똥냄새를.

하여튼, 그때 기저귀를 갈면서 아들에게 말했던 것 같다.
"아들아, 넌 언제 기저귀 혼자 갈래?"

그런데.
그렇게 살아가던 어느 날.
그날도 역시 밤늦게 퇴근했다. 피곤한 마님은 내가 들어올 때쯤 되니 주무시고 계시고..
거실에 있던 아들 녀석이 나를 반겼다. 이뻤다. 안아주고 싶었다.
역시 아빠를 반기는 것은 아들밖에 없구나. 두 팔을 벌리고 한 달음에 다가갔다.

그런데.
어디선가 냄새가 났다. 순간 나는 내가 개똥 밟은 줄 알았다.
신발에 묻었나 살펴보니 안 묻었다. 난 심각해졌다. 양말에 묻었나 싶어 양말을 벗어 냄새를 맡아 보았다.
역시 발냄새만 났다. 더 심각해졌다. 옷에 묻었나 싶어 옷을 다 벗어들고 냄새를 맡아 보았다.

한참을 설레발을 치다 보니 결정적으로 잊고 있던 것이 생각이 났다.
왜 아들을 먼저 살펴볼 생각을 못했을까?
그렇다. 내 아들이 범인인 것 같았다. 그래서 바로 아들에게 달려가서 엉덩이를 깠다.
그런데 왠걸? 기저귀가 보여야 하는데 살이 보였다. 깨끗했다.

용감하게도 아들에게 기저귀를 안채우고 데리고 있었던 마님의 용기에 찬사를 보냈다.
하긴, 우리 마님은 기저귀를 갈다가 아들녀석이 오줌을 싸면 순간적으로 기저귀로 오줌을 막을 정도로 순발력이 있었다.하여간 아들의 깨끗한 엉덩이를 보고 안심하고 아들을 안아 들었다.
그런데 냄새가 몇배로 심해졌다..ㅠ.ㅠ. 에이씨.

아들을 데리고 욕실로 들어가 바지를 벗기고 엉덩이를 씻겼다.
똥구녕 사이로 똥이 고개를 내밀고 있었다. 마치 나를 놀리는 것 같았다. 아니, 인사했나? ㅠ.ㅠ
깨끗하게 씻기고 수건으로 물기를 닦고 나니 아들 녀석 엉덩이가 뽀송뽀송했다.
들어간 김에 나도 씻고 나와서 잠을 자려고 들어가는데, 왜일까?
거실에서 여전히 똥냄새가 났다. 이런 망할. 도대체 뭐야, 이건?

그때부터 똥냄새를 추적하기 시작했다.
거실 구석구석을 뒤진 끝에 범인을 잡았다.
범인은 부엌 한구석에 놓여 있던 휴지통이었다.
쓰레기통에는 우리 아들의 소중한 똥(?)이 잔뜩 묻어 있는 기저귀가 거꾸로 쳐박혀 있었다.

난, 순간 안방으로 돌진해서 마님을 들이받으려고 깨웠다.
아니, 이 여자가 왜 아들 기저귀를 갈고 나서 똥을 그대로 쓰레기통에 쳐박아 놔?
그런데 우리 마님. 자기는 기저귀를 간 적이 없다면서, 잘 자는 사람 깨웠다고 오히려 나를 혼냈다.
들이받지 않기를 잘했다고 안도의 한숨을 쉬었던 기억이 난다.

그렇다.
아빠의 독백을 들었던 우리 아드님께서 자기 혼자 똥을 싸고 기저귀를 벗어서 쓰레기통에 쳐박아 놓은 것이다!!!
나는 똥냄새로 우리 아들의 진가를 발견했다!

이 얼마나 천재와 같은 아들인가?
그 나이에 혼자 똥싼 기저귀를 벗다니. 옷에 똥도 안 묻히고.
그 나이에 아빠를 감쪽같이 속였다. 얼마나 대단한가?
우리 아들 대단하다고 혼자 신나서 잠들 때까지 안고 거실에서 돌아다녔던 기억이 엊그제의 일 같다.

그런데 갑자기 짜증이 난다. 주변에서 냄새가 나는 것 같다.
그 지독했던 예람이 똥냄새가... 무려 7~8년이 지난 지금도 생각난다.
에이. 디러.
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/732

세월의 흐름은 잡을 수 없다.
첫째 예람이가 태어나서 같이 웃고, 기뻐했던 적이 엊그제 같은데 벌써 10년이 흘렀다.
그리고 둘째 예린이가 태어난지도 8년이라는 시간이 흘렀다.

솔직이 이제 더 이상 육아일기를 쓸 내용이 없을 줄 알았다.
애들이 그만큼 컸기 때문에....

하지만, 왠걸?
아이들은 나이에 상관없이 자라면서 끊임없이 나에게 사건을 만들고
웃음짓게 하는 존재들이라는 것을 다시금 되새기게 된다.

우리 딸, 예린. 8년의 시간을 보낸 우리 따님이 이제 멋의 세계를 알았다.

사건은 이렇다.
맛있게 수박을 먹은 후, 나는 방에 들어가 누웠다.
그리고 우리 예린. 아빠를 너무 좋아하는 우리 예린이가 아빠를 따라서 안방으로 들어왔다.

그.런.데. 뒤이어 들어온 우리 마님. 갑자기 나보고 한마디 하신다.

"자기야, 얘좀 봐."
"왜?"
"갑자기 한 밤중에 예린이가 립스틱을 발랐어. 요즘 얘가 왜 이렇게 멋을 내?"

순간 움찔해서 돌아보니 정말 예린이의 입술 색깔이 분홍색으로 빛나고 있었다.
저건.. 도대체 뭐라고 표현해야 할까.....
그냥 안 어울렸다. 우리 이쁜 딸 주둥이가 조동이가 되어 부렀어. 이상해졌어..ㅠㅠ

순간 떠오르는 생각.
"내일이면 잊으리, 꼭 잊으리. 립스틱 짙게 바르고~~~~ "

하지만, 그 나이 때는 멋을 내려고 하는 시기라 그런가보다 생각도 들었다.
다만....
딸아. 아빠한테 엄마 화장품 발라주려고 달라붙지만 말아 다오...
받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/731

08. Update API

Elastic Search/03. APIs 2015/05/20 13:07 용비

Update API 제공된 script 따라 document를 업데이트한다. Operation index로부터 document 조회하고 script 실행하여 결과를 index 저장한다. 물론 조회나 reindex하는 과정에서 업데이트가 없다는 것은 버전으로 확인할 있다.


operation document full reindex 의미하며, network roundtrip 제거하고 get operation index사이에 버전 변경으로 인한 충돌을 감소시켜야 함에 유의하라. 이러한 특징을 해결하기 위해서 _source field 필요하다.


예를 들어 다음 간단한 document index해보자.


curl -XPUT localhost:9200/test/type1/1 -d '{
  
"counter" : 1,
  
"tags" : ["red"]
}'


이제 counter 증가시키는 script 실행할 있다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.counter += count",
  
"params" : {
      
"count" : 4
  
}
}'


또한 태그 리스트에 태그를 추가할 수도 있다. (만약 태그가 존재하더라도 리스트이기 때문에 추가된다.)


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.tags += tag",
  
"params" : {
      
"tag" : "blue"
  
}
}'


Document 새로운 field 추가할 있다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.name_of_new_field = \"value_of_new_field\""
}'


Document로부터 field 삭제할 수도 있다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.remove(\"name_of_field\")"
}'


태그가 blue document 삭제하거나, blue 아닐 경우 삭제하지 않을 수도 있다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.tags.contains(tag) ? ctx.op = \"delete\" : ctx.op = \"none\"",
  
"params" : {
      
"tag" : "blue"
  
}
}'


[NOTE]

3 operator assignment 다루는 것을 알아야 한다. Assignment operation 3 operator 비해서 우선순위가 낮다. 다음 항목들을 비교해 보자.


// Will NOT update the tags array
ctx
._source.tags.contains(tag) ? ctx.op = \"none\" : ctx._source.tags += tag
// Will update
ctx
._source.tags.contains(tag) ? (ctx.op = \"none\") : ctx._source.tags += tag
// Also works
if (ctx._source.tags.contains(tag)) { ctx.op = \"none\" } else { ctx._source.tags += tag }


Update API 통해서 또한 document 일부분만 전송할 있다. 전송된 내용은 이미 존재하는 document merge된다. (간단히 말하자면 recursive merge, object inner merge, "key/value" array replace하는 것이다.)


예를 들면 다음과 같다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"doc" : {
      
"name" : "new_name"
  
}
}'


Doc script 지정하면 doc은 무시된다. Script내에 document 일부분에 해당하는 field pair 넣는 것이 가장 좋다. 기본적으로 doc 지정되면, document merge process 어떤 변화를 일으키지 않더라도 항상 update된다. Detect_noop true 설정하면 Elasticsearch에서 변경사항이 있는지를 체크하고 아니면 update request noop 된다. 예를 들면 다음과 같다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"doc" : {
      
"name" : "new_name"
  
},
  
"detect_noop": true
}'


Request 보내지기 전에 name new_name이라면 전체 update request 무시한다.


Upserts


Elasticsearch Update API에는 upsert도 있다. Document 이미 존재하지 않으면, upsert element content 새로운 document index 것이다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"script" : "ctx._source.counter += count",
  
"params" : {
      
"count" : 4
  
},
  
"upsert" : {
      
"counter" : 1
  
}
}'


Document 없으면 스크립트를 통해서 client에는 알려지지 않은 business logic 사용하여 document content 초기화하도록 있다. 이런 경우에는 새로운 scripted_upsert parameter true 설정하면 된다.


curl -XPOST 'localhost:9200/sessions/session/dh3sgudg8gsrgl/_update' -d '{
  
"script_id" : "my_web_session_summariser",
  
"scripted_upsert":true,
  
"params" : {
      
"pageViewEvent" : {
              
"url":"foo.com/bar",
              
"response":404,
              
"time":"2014-01-01 12:32"
      
}
  
},
  
"upsert" : {
  
}
}'


Default scripted_upsert 설정은 false이다. 이것은 script insert 위해서는 실행되지 않음을 의미한다. 그러나 위와 같은 시나리오에서처럼 새로운 "indexed scripts" feature 이용하여 저장된 중요한 (non-trivial) script 사용할 있다. 스크립트를 통해서 여러 page view event 기반한 web session 기간 (duration) 같은 특징들을 뽑아낼 수도 있다. Client에서는 blank "upsert" document 제공하거나 params element 넘겨진 event 사용하여 최대한 상세하게 채워서 script 실행할 수도 있다.


마지막으로 upsert 기능은 doc_as_upsert 지원한다. 제공된 document 기존에 존재하지 않는 document 경우에 insert된다. 이것은 Elasticsearch 전송되는 데이터의 양을 감소시킬 것이다.


curl -XPOST 'localhost:9200/test/type1/1/_update' -d '{
  
"doc" : {
      
"name" : "new_name"
  
},
  
"doc_as_upsert" : true
}'


Parameters


Update operation index API처럼 유사한 parameter 지원한다.


Routing : document 적합한 shard route하는데 사용하는 설정

Parent : routing 단순 설정

Timeout : shard 다시 사용가능해질 때까지 기다리는 시간

Replication : delete/index operation (sync, async) 대한 replication type. 1.5.0에서 deprecated.

Consistency : index/delete operation write consistency

Refresh : 전체 index 아니라 적합한 primary replica shard operation 발생한 이후 즉시 refresh. 따라서, update document 바로 검색 결과로 나타난다.

Fields : update document로부터 적합한 fields 리턴. 전체 update source 리턴하기 위해서 _source 지원.

Version & version_type : Update API Elasticsearch 내부에서 지원하는 versioning을 사용함. Update되는 동안 document 변경되지 않았음을 version으로 판별. 특정 version document update하기 위해서 version parameter 사용할 수도 있음. Version type force 설정하면 강제로 document update하고 새로운 version 부여됨. (사용하는데 주의할 ! Force 사용하면 document 변경되지 않았음을 보증할 없음.) external & external_gte version type 지원되지 않음


조회한 document 그것을 indexing / deleting하는 사이에 version 충돌이 발생하면 몇번이나 retry해야 하는지를 설정하는 Retry_on_conflict 지원한다. Default 0이다.


또한 ctx._ttl 사용하여 document ttl update 있다. 그리고 ctx._timestamp 사용하여 document timestamp update 있다. 만약 timestamp update되지 않았고, _source로부터 추출된다면 update date 설정할 것이다.


_source 추가로 다음과 같은 variable들을 ctx map 이용할 있다. : _index, _type, _id, _version, _routing, _parent, _timestamp, _ttl

받은 트랙백이 없고, 댓글이 없습니다.

댓글+트랙백 RSS :: http://www.yongbi.net/rss/response/730