Slide 1

Slide 1 text

εϥΠυதͷ୹ॖURL (goo.gl) ͸Speaker DeckରࡦͰ͢ɻ KeynoteͩͱURL͕ΫϦοΧϒϧʹͳΒͳ͍ͨΊɻ

Slide 2

Slide 2 text

͋ͷʰ̋̋Λࢧ͑Δٕज़ʱ͔Β10ϲ݄ https://goo.gl/XUlD4p

Slide 3

Slide 3 text

ύϫʔΞοϓͯ͠ؼͬͯࢀΓ·ͨ͠ʂ

Slide 4

Slide 4 text

̋̋̋Λࢧ͑Δٕज़ 2017.02.17 ૿ాو࢜(@masutaka) 1.5ഒʂ

Slide 5

Slide 5 text

̋ϩ̋Λࢧ͑Δٕज़ 2017.02.17 ૿ాو࢜(@masutaka)

Slide 6

Slide 6 text

̋ϩάΛࢧ͑Δٕज़ 2017.02.17 ૿ాو࢜(@masutaka)

Slide 7

Slide 7 text

ϒϩάΛࢧ͑Δٕज़ 2017.02.17 ૿ాو࢜(@masutaka)

Slide 8

Slide 8 text

https://masutaka.net/chalow/

Slide 9

Slide 9 text

࣮ԋ

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

ࠓճͷݕࡧͷ࢓૊Έ ਓ → search.masutaka.net → nginx → elasticsearch

Slide 12

Slide 12 text

ͬ͘͟Γઆ໌ • ϑϩϯτΤϯυ͔Βɺmasutaka.netʹ͋Δ ElasticsearchͷAPIΛୟ͍ͯϒϩάهࣄΛݕࡧ • Elasticsearchͷهࣄσʔλ͸σϓϩΠͷͨͼʹ ߋ৽͞ΕΔ • ANDݕࡧͱNOTݕࡧ͚࣮ͩ૷ͨ͠

Slide 13

Slide 13 text

Ϟνϕʔγϣϯ

Slide 14

Slide 14 text

• ιʔγϟϧPLUSͷސ٬޲͚ϚχϡΞϧΛ HTMLԽͨ࣌͠ʹɺElasticsearchΛશจݕࡧ Τϯδϯͱͯ͠࢖͑Δ͔ʁͷݕূ • ػೳͱ࣮૷͠΍͢͞ • ElasticsearchΛϩάͷՄࢹԽ͚ͩͰ͸ͳ ͘ɺશจݕࡧΤϯδϯͱͯ͠΋࢖͍͍ͨ

Slide 15

Slide 15 text

ͦ΋ͦ΋ ϚελΧωοτͱ͸ https://masutaka.net

Slide 16

Slide 16 text

https://masutaka.net/chalow/

Slide 17

Slide 17 text

• ͘͞ΒͷVPS্ͰࣗυϝΠϯΛӡ༻ • ٕज़ϝϞͷެ։৔ॴ • ֤छٕज़ͷ࣮ݧ৔ • fluentd, Elasticsearch, Kibana, BigQuery, http2, Mackerel, New Relic, Datadog, Vue.js,…

Slide 18

Slide 18 text

ߏ੒ਤ

Slide 19

Slide 19 text

σϓϩΠ 1. GitHubͷmasterʹcommit͕௥Ճ͞ΕΔͱɺ CircleCI͕capistranoΛ࢖ͬͯࣗಈσϓϩΠ 1. HTMLͷੜ੒ͱElasticsearch΁ͷ౤ೖ 2. pushoverͰiPhoneʹ௨஌

Slide 20

Slide 20 text

• 1ͭͷʮChangeLogϝϞʯϑΝΠϧ͔ΒϒϩάΛੜ੒ • chalowͱ͍͏Perl੡ͷHTMLδΣωϨʔλΛΧελ ϚΠζ • 2001-12-30͔Βॻ͖࢝Ίͨ • 2008-09-25ʹWebαΠτͱͯ͠ެ։ • 2009-05-17͔Βmasutaka.netͱͯ͠Քಇத • 2017-02-17ݱࡏɺ37,268ߦ 1,245هࣄ http://chalow.org

Slide 21

Slide 21 text

ϚελΧͷChangeLogϝϞʢ࣮ମʣ

Slide 22

Slide 22 text

ChangeLogϝϞͱ͸

Slide 23

Slide 23 text

• Unix Magazine 2002೥1݄߸ʰUnixͷϝϞٕज़ʱͰੈʹ஌Β ΕΔ • ChangeLogܗࣜΛ࠾༻ͨ͠1ͭͷςΩετϑΝΠϧ • ৘ใ͕1ͭͷϑΝΠϧʹ·ͱ·Δɻϙέοτ1ͭݪଇ • ৽͍͠ϝϞ͸ඞͣҰ൪্ʹͳΔͨΊɺ੔ཧͷඞཁ͕ͳ ͍ • ςΩετϑΝΠϧͳͷͰɺ࢖͍׳ΕͨΤσΟλͰૉૣ͘ ฤूͰ͖Δɻকདྷʹ౉ͬͯσʔλͷҠߦΛ৺഑͢Δඞ ཁ΋ͳ͍ http://0xcc.net/unimag/1/

Slide 24

Slide 24 text

ͲͷΑ͏ʹ࣮૷͔ͨ͠

Slide 25

Slide 25 text

࠾༻ͨ͠πʔϧ • Vue.js-2.1.10 + axios-0.15.3 • nginx-1.11.3 • Elasticsearch-5.1.1 • Oga-2.8

Slide 26

Slide 26 text

JavaScript • ҙ֎ͱ΍Δ͜ͱ͕ଟ͔ͬͨ • FlameworkʢVue.jsʣ • HTTP request with Ajaxʢaxiosʣ • ݕࡧΫΤϦ૊Έཱͯʢࣗલʣ • Paginationʢࣗલʣ • Routingʢࣗલʣ

Slide 27

Slide 27 text

• ർΕͨͷͰɺޙ͸URL͚ͩͰࣦྱ͠·͢ • https://masutaka.net/chalow/search.html • https://masutaka.net/chalow/search.js

Slide 28

Slide 28 text

ElasticsearchͷݕࡧΫΤϦ https://www.elastic.co/guide/en/elasticsearch/reference/5.1/ query-dsl-bool-query.html https://goo.gl/WVxFGo

Slide 29

Slide 29 text

“ָ͍͠” { "query": { "bool": { "should": [ { "term": { "title": "ָ͍͠" } }, { "term": { "body": "ָ͍͠" } } ], "minimum_should_match": 1 } } } OR هࣄλΠτϧ هࣄຊจ

Slide 30

Slide 30 text

“ָ͍͠ emacs” { "query": { "bool": { "must": [ { "bool": { "should": [ { "term": { "title": "ָ͍͠" } }, { "term": { "body": "ָ͍͠" } } ], "minimum_should_match": 1 } }, { "bool": { "should": [ { "term": { "title": "emacs" } }, { "term": { "body": "emacs" } } ], "minimum_should_match": 1 } } ] } } } AND

Slide 31

Slide 31 text

ָ͍͠ -emacs { "query": { "bool": { "must": [ { "bool": { "should": [ { "term": { "title": "ָ͍͠" } }, { "term": { "body": "ָ͍͠" } } ], "minimum_should_match": 1 } } ], "must_not": [ { "bool": { "should": [ { "term": { "title": "emacs" } }, { "term": { "body": "emacs" } } ], "minimum_should_match": 1 } } ] } } } NOT

Slide 32

Slide 32 text

nginxͷઃఆ upstream application-elasticsearch { server 0.0.0.0:9200; } server { listen 443 ssl http2; server_name search.masutaka.net; # (snip) location / { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Headers Content-Type; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Host $host; proxy_pass http://application-elasticsearch/chalow/article/_search; } } ElasticsearchΛ·Δ͝ͱެ։ ͯ͠͸͍ͳ͍͔Βେৎ෉ͩ ͱ͸ࢥ͏ɻ

Slide 33

Slide 33 text

kuromoji pluginͷΠϯετʔϧ $ cd /usr/share/elasticsearch $ sudo bin/elasticsearch-plugin install analysis-kuromoji $ sudo service elasticsearch restart

Slide 34

Slide 34 text

ςϯϓϨʔτͷ౤ೖ $ curl -X PUT 'http://localhost:9200/_template/chalow' -d ' { "template" : "chalow", "settings": { "index": { "analysis": { "tokenizer": { "kuromoji_user_dict": { "type": "kuromoji_tokenizer", "mode": "search" } } } } }, "mappings": { "article": { "properties": { "title": { "type": "string", "analyzer": "kuromoji", "fielddata": true, "fields": { "keyword": { "type": "keyword" } } }, "body": { "type": "string", "analyzer": "kuromoji", "fielddata": true, "fields": { "keyword": { "type": "keyword" } } } } } } } '

Slide 35

Slide 35 text

هࣄσʔλͷ౤ೖ #!/bin/sh -eu TMP_JSON=chalow-es.json ES_URL=http://localhost:9200 ./script/html2json > $TMP_JSON curl -s -X DELETE $ES_URL/chalow curl -s -X POST $ES_URL/_bulk --data-binary @$TMP_JSON > /dev/null ※ σϓϩΠ࣌ʹ࣮ߦ͞ΕΔɻ./script/html2json͸Oga gemΛ࢖ͬͯHTMLͳهࣄΛύʔ ε͠ɺElasticsearch Bulk POSTͷͨΊͷjsonΛ࡞Δɻίʔυ͸ https://goo.gl/atnXVm

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

Vue.jsͱͷग़ձ͍ • ReactɺAngularʹͳ͡Ίͳ ͔ͬͨ๻ʹखΛࠩ͠৳΂ ͯ͘ΕͨVue.js - Qiita [^1] • ࢲͨͪ͸ͳͥReactͰ͸ͳ ͘Vue.jsΛબΜͩͷ͔ | ϓ ϩάϥϛϯά | POSTD [^2] [^1]: https://goo.gl/kNE5If, [^2]: https://goo.gl/bB5Ej5

Slide 38

Slide 38 text

ྑ͍ͱ͜Ζ • ϋʔυϧͷ௿͞ • JSͷϏϧυ؀ڥΛߏஙͤͣʹ࢝ΊΒΕΔ • jQueryͰࢭ·͍ͬͯΔਓͰ΋ϦΞΫςΟϒϓ ϩάϥϛϯάΛ࢝ΊΒΕΔ • ೔ຊޠΨΠυΛ1೔΍Ε͹ɺಈ͘΋ͷΛ࡞ΕΔ https://goo.gl/mkDKpE

Slide 39

Slide 39 text

Elasticsearchʹอଘͨ͠ͱ͍͏ ͜ͱ͸ʁ

Slide 40

Slide 40 text

KibanaͰՄࢹԽग़དྷΔʂ

Slide 41

Slide 41 text

࣮ԋ

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

No content

Slide 44

Slide 44 text

ࣗݾຬ଍͕ಘΒΕ·ͨ͠ɾɾɾʂ

Slide 45

Slide 45 text

݁ہͷͱ͜ΖɺElasticsearch͸ ݕࡧʹ࢖͑Δʁ

Slide 46

Slide 46 text

• ֶशίετ͸ߴ͍͕ɺݕࡧΤϯδϯͱͯ͠ ͸༏लͩͱࢥͬͨɻ΍͸ΓKuromoji͕σΧΠ • ॳظઃఆͰ΋ͦͦ͜͜࢖͑ΔɻΘ͔ͪॻ͖ ͷνϡʔχϯά͸ඞཁͦ͏ • όοΫΤϯυ͔Β࢖͑͹ɺΞΫηεݖΛߟ ྀͨ͠ݕࡧ΋Ͱ͖Δ͸ͣ • ֶशίετߴ͍ͳʔʢ೰Έʣ

Slide 47

Slide 47 text

ͱ͜ΖͰݕࡧͱ͍͑͹ʁ

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

Google Custom SearchͰ΋ ࣮૷ͯ͠Έͨ

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

࣮ԋ

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

Google Custom Search • GoogleͷΤϯδϯΛ࢖ͬͯɺ೚ҙͷαΠτΛݕࡧͰ͖ΔαʔϏε • GCP্͔ΒAPI KEYͱENGINE IDΛൃߦ͢Ε͹࢖͑Δ • ແྉ࿮ͷར༻੍ݶ͸100 queries/day • https://goo.gl/DgHyop • ࠷௿ྉۚ͸100USDʢ20,000 queries/yearʣ • https://goo.gl/wdxEXx

Slide 54

Slide 54 text

ײ૝ • ͕͢͞ੈք࠷ڧͷϚωʔδυݕࡧαʔϏε • GETϦΫΤετͰ؆୯ʹ࢖͑ͨ • ͋ΕɺݸਓαΠτఔ౓ͳΒ͜ͷར༻੍ݶͰ΋େৎ෉͔΋ • Elasticsearchͱҧͬͯɺࡉ͔ͳௐ੔͸Ͱ͖ͳ͍ • ϖʔδ಺ͷݕࡧίϯςϯπΛࢦఆ͢Δͱ͔

Slide 55

Slide 55 text

ճސ

Slide 56

Slide 56 text

೥຤͘Β͍͔Βߏ૝͕ݻ·Γ ࢝ΊΔ

Slide 57

Slide 57 text

(´-`).oO(Elasticsearch͸࠷৽ʹ͠ ͓͔ͯ͘)

Slide 58

Slide 58 text

https://goo.gl/hfXBZe

Slide 59

Slide 59 text

• ʗ(^o^)ʘ Elasticsearch 3೥෼ͷσʔλΛશ ͯϩετ • ʗ(^o^)ʘ ϚΠάϨʔγϣϯΨΠυʹ͸ ै͍·͠ΐ͏ https://goo.gl/VY62Hh

Slide 60

Slide 60 text

(´-`).oO(SSLূ໌ॻʹ search.masutaka.netͷ௥Ճ͕ඞཁͩͳ)

Slide 61

Slide 61 text

https://goo.gl/liOdYN

Slide 62

Slide 62 text

• ʗ(^o^)ʘ StartSSL͕ೝূہͱͯ͠ऴΘͬ ͯͨɻ͔͠͠·ͩൢച͍ͯ͠Δͱ͍͏ҋ • ʗ(^o^)ʘ ஌ࣝෆ଍͔Βແବʹ՝ۚͨ͠ • Let’s EncryptʹҠߦ

Slide 63

Slide 63 text

(´-`).oO(Vue.jsͷྑ͞ΛΠϯϑ ϥͷਓʹ΋஌ͬͯ΋ΒΘͶ͹)

Slide 64

Slide 64 text

ʗ(^o^)ʘ ̏िʹ౉ͬͯ঺հ 1. ঺հฤ 2. Ajaxฤ 3. jQueryͱͷҧ͍ฤ

Slide 65

Slide 65 text

(´-`).oO(ٱʑʹ΋͘΋͘ձʹ ग़ͯΈΔ͔)

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

• ʗ(^o^)ʘ ։ళ࣌ؒΛա͔͗ͯΒɺ߄ͨ ͩ͘͠ళͷਓ͕΍͖ͬͯͨɻ౰൪ͷਓ͕ ৸๥ʁ • ʗ(^o^)ʘ ॳΊͯߦͬͨίϫʔΩϯάε ϖʔεͩͬͨͷͰɺ͏Ζͨ͑ͨ

Slide 68

Slide 68 text

(´-`).oO(΋͘΋͘ձͷ੒ՌΛ ࿩ͨͯ͘͠࢓ํ͕ͳ͍)

Slide 69

Slide 69 text

ʗ(^o^)ʘ ΋͘΋͘ձͷ࠷ޙ ͰωλόϨ

Slide 70

Slide 70 text

ࠓޙͱ΋ϚελΧωοτΛ ΑΖ͓͘͠ئ͍͠·͢ɻ