ホエールテック株式会社 ホエールテック株式会社

  • ブログ

全文検索エンジンを使ってみよう・その2〜Elasticsearch追加・検索編

最新 Laravel 11 、めっちゃスリムになりましたね。テンション爆アゲのsoobeです!

今回のブログのテーマは、Elasticsearch(エラスティックサーチ)の追加・検索機能の実装です。

前回、Elasticsearchの開発環境構築の記事を上げました。開発環境をまだ構築していない方は、ぜひご利用ください!

今回の目標です

・Elasticsearchに映画データを新規登録できる。

・インデックスとドキュメントの関係を理解できる。

・Elasticsearchの映画データを全文検索できる。

*この記事では、Mac(Apple Silicon)+ Docker Desktop を使用しています。

1. Elasticsearch データ新規登録プログラムを作成しよう

python/src配下に、空のstore_elasticsearch.pyを新規作成してください。

.
├── elasticsearch
│   └── docker-compose.yml
└── python
    ├── Dockerfile
    ├── docker-compose.yml
    ├── requirements.txt
    └── src
        ├── __init__.py
        ├── test_connect_elasticsearch.py
        └── store_elasticsearch.py

store_elasticsearch.pyに以下コードを貼り付けてください。

from elasticsearch import Elasticsearch

ELASTIC_SEARCH_HOST = "<--ここにプライベートIPを貼り付けてください-->"
ELASTIC_CERT_FINGERPRINT = "<--ここにELASTIC_CERT_FINGERPRINTを貼り付けてください-->"
ELASTIC_PASSWORD = "elastic"

# Elasticsearchインスタンスを作成
es = Elasticsearch(    
    f"https://{ELASTIC_SEARCH_HOST}:9200",
    ssl_assert_fingerprint=ELASTIC_CERT_FINGERPRINT,
    basic_auth=("elastic", ELASTIC_PASSWORD),
)

# 登録するドキュメントのリスト
documents = [
    {
        "title": "ファーザー",
        "content": "アンは80歳になった父親、アンソニーに認知症の兆候が見え始めたのを心配していた。アンソニーにヘルパーを付けようとしたアンだったが、気難しいアンソニーは難癖を付けてはヘルパーを追い出す始末だった。しかし、アンソニーの病状は悪化の一途を辿り、記憶が失われていくだけではなく、自らが置かれた状況すら把握できなくなっていった。困惑するばかりのアンソニーは苛立ちを募らせ、アンに当たることもあった。アンはそんな父親を懸命に支えていたが、気力と体力は消耗するばかりであった。"
    },
    {
        "title": "メメント",
        "content": "『メメント』(英語: Memento)は2000年のアメリカ合衆国の映画。当時未公開のジョナサン・ノーランによる短編小説『Memento Mori(英語版)』の映画化であり、クリストファー・ノーラン脚本・監督によるミステリー、スリラー作品である。妻を殺されそのショックから10分間しか記憶を保てないという記憶障害を抱えることになった主人公レナード・シェルビーが、妻を殺害した犯人を探す過程を描いており、ストーリーを終わりから始まりへ、時系列を逆向きに映し出していく。"
    },
    {
        "title": "フォレスト・ガンプ 一期一会",
        "content": "1985年にウィンストン・グルームが発表した小説『フォレスト・ガンプ』(日本語訳は講談社より1994年12月出版。小川敏子訳)をエリック・ロスが脚色して製作された映画だが、原作からは大きく改変されている。人より知能指数は劣るが、純真な心と恵まれた身体、母への愛とある1人の女性への一途な思いを持つ主人公フォレスト・ガンプ(「うすのろフォレスト」「間抜けなフォレスト」)が、心ない人からは嘲りを受けつつも、それ以上に良き心を持つ周囲の人々の協力を受けて数々の成功を収め、同時に幸福を周囲にもたらしていく半生を、1950 - 80年代のアメリカ合衆国の歴史を交えながら描いた、笑いあり涙ありのヒューマンドラマ。タイトルの「フォレスト・ガンプ」は主人公の名前。「フォレスト」は白人至上主義団体であるクー・クラックス・クランの結成者として知られるネイサン・ベドフォード・フォレストから。「ガンプ」(gump) はアラバマ州の方言で、「うすのろ」「間抜け」「愚か者」を意味する"
    },
    {
        "title": "ショーシャンクの空に",
        "content": "1947年、メイン州ポートランド。若くして銀行の課長を務める優秀な銀行員アンドリュー・デュフレーン (アンディ)は、妻とその愛人を射殺した罪に問われる。無実を訴えるも終身刑の判決が下り、劣悪なショーシャンク刑務所への服役が決まる。ショーシャンクでは、長年服役する「調達屋」ことエリス・ボイド・レディング(レッド)が、もう何度目かとなる仮釈放の審査を受け、更生したことを訴えるがやはり却下される。レッドが落胆し部屋を出ると、アンディを含む新しい受刑者達が護送されて来る。アンディら新入り達はノートン所長とハドリー主任刑務官から脅しを含めたショーシャンク刑務所の紹介をされ、その晩に取り乱した一人の新人受刑者がハドリーから過剰暴力を受けて死んでしまう。孤立していたアンディはやがてレッドに声をかけ、鉱物採集の趣味のため小さなロックハンマーを注文する。それをきっかけにアンディはレッドと交友を重ね始める。他方、アンディは荒くれ者のボグズとその一味に性行為を強要され、抵抗のため常に生傷が絶えない生活が続いた。1949年、アンディは屋根の修理作業中、ハドリーの遺産相続問題を知り、財務経理の知識を駆使し作業仲間達へのビールと引き換えに解決策を提案する。ビールを手に入れ仲間達から尊敬される一方で、ハドリーら刑務官からも一目置かれるようになる。その後ボグズらがアンディを襲って全治1ヶ月の重傷を負わせるも、彼はハドリーに半殺しにされ、以後、アンディを襲う者はいなくなる。アンディが治療を終え自分の房に戻ってくると、レッドに注文していたリタ・ヘイワースの大判ポスターが退院祝いとして置かれていた。やがて、アンディは図書係に配置換えとなり、もう50年も服役している老囚人ブルックスの助手となる。だが、その本当の目的は所長や刑務官達の税務処理や資産運用をアンディに行わせるためだった。アンディは有能な銀行家としての手腕を発揮する一方で、名ばかりだった図書係としても精力的に活動を始め、州議会に図書館予算の請求を毎週送るようになる。1954年、ブルックスに仮釈放の許可が下りるが、50年服役した老人は塀の外の生活への恐れから取り乱す。アンディらに説得され、仮釈放を受け入れるが、結局、外の生活に馴染むことはできず、最期は首を吊って死んでしまう。死の間際に送られた感謝の手紙を読んでアンディとレッドは苛まれる。一方、手紙に根負けした州議会はわずかばかりの寄付金と古書をショーシャンク刑務所に送ってくる。アンディは送られてきた荷物の中に『フィガロの結婚』(第3幕『手紙の二重唱』)のレコードを見つけ、それを勝手に所内放送で流したことで懲罰房送りとなる。その後、仲間達からレコードを流した理由を尋ねられ、アンディは「音楽と希望は誰にも奪えないものだ」と説明するが、レッドは「そんなもの(希望)は塀の中じゃ危険だ」と反論する。1963年、アンディが州議会にさらに手紙を送り続けた結果、年度毎の予算まで獲得し、倉庫同然だった図書館は囚人達の娯楽と教養を得る場となっていた。その頃所長は、囚人達の社会更生を図るという名目で、彼らを労働力として野外作業をさせ始め、裏ではそのピンハネや土建業者達からの賄賂を受け取り始める。そしてアンディは「ランドール・スティーブンス」という架空の人物を作り出し、その多額の不正蓄財を見事に隠蔽していた。1965年、新たに入所したコソ泥の青年トミーは、すぐにレッドの仲間達と打ち解け、アンディも彼を気に入る。更生を望むトミーにアンディは文字の読み書きから勉強を教え始め、やがて高校卒業資格を申請するにまで至る。トミーはアンディの過去を知ると、その真犯人に心当たりがあることを話す。別の刑務所にいた囚人が強盗を行った際、その場にいて撃ち殺したのがアンディの妻と愛人だったという自慢話をしていたのだ。アンディは所長に再審請求したいと頼み込むが、優秀な経理担当者であると同時に不正蓄財を知っている彼を自由にさせる気のない所長は、アンディを懲罰房に入れ考えを改めるよう迫る。1ヶ月経っても折れないアンディに業を煮やした所長は、冤罪証明の鍵を握るトミーを脱走を企てたとして射殺してしまう。トミーの死から1ヶ月後、アンディは再び不正経理を行うことを条件に懲罰房から出される。しかし、アンディの様子はどこかおかしく、メキシコのジワタネホ(英語版)の話をしたり、レッドに要領を得ない伝言を残す。レッドら仲間達はアンディが自殺を考えていると疑い、嵐の晩に心配が募る。翌朝の点呼の際、アンディが房から消えていることが発覚する。所長やハドリーもアンディの房に向かい、リタ・ヘイワースからマリリン・モンローへ、そしてラクエル・ウェルチへと代替わりしていたポスターの裏の壁に大穴が開いていることを見つけ出す。アンディは約20年間ロックハンマーで壁を掘り続け、ついに1966年、脱獄したのだった。アンディはその足で銀行に向かいスティーブンスに成りすまして所長の不正蓄財を引き出すと同時に告発状を新聞社へ送り、難なくメキシコへ逃亡する。そしてアンディの告発状によってハドリーは逮捕され、所長は拳銃自殺する。間もなくレッドは服役40年目にしてようやく仮釈放されるが、ブルックスと同様に外の生活に順応できない。ブルックスと同じ悲劇への道を辿りかけるが、レッドはアンディの伝言を信じてメキシコのジワタネホへ向かう。そして、美しく青い海の浜で悠々自適の生活を送るアンディと再会し、喜びの抱擁を交わしたのだった。 - 80年代のアメリカ合衆国の歴史を交えながら描いた、笑いあり涙ありのヒューマンドラマ。タイトルの「フォレスト・ガンプ」は主人公の名前。「フォレスト」は白人至上主義団体であるクー・クラックス・クランの結成者として知られるネイサン・ベドフォード・フォレストから。「ガンプ」(gump) はアラバマ州の方言で、「うすのろ」「間抜け」「愚か者」を意味する。"
    },
    {
        "title": "戦場のピアニスト",
        "content": "1930年代後半、ポーランドのワルシャワ。ユダヤ人、ウワディスワフ・シュピルマンはピアニストとして活躍していた。しかし1939年9月、その生活が一変する。第二次世界大戦が勃発し、ナチスドイツはポーランド侵攻を開始、シュピルマンがスタジオで録音をしていたラジオ局はドイツ空軍による突然の爆撃を受け被害を受ける。なんとかスタジオを脱出したシュピルマンは混乱の中で友人ユーレクの妹ドロタと出会い、以降、僅かばかりの友好関係を築く。帰宅した彼は、イギリスとフランスがドイツに対して宣戦布告をしたことを海外のラジオ放送で知り、戦争は早期に終結すると信じて家族と共に喜ぶ。しかし、状況は好転する事がなかった。ワルシャワはドイツ軍に占領され、親衛隊と秩序警察による過激な弾圧によって、ユダヤ人の生活は悪化してゆく。ダビデの星が印刷された腕章をつけることが義務付けられ、喫茶店や公園への立ち入りも制限される中、少しでも目立った行動をとるユダヤ人はナチス親衛隊の暴力にさらされるのだった。1940年後半には、ユダヤ人たちはワルシャワ・ゲットーに押し込められ、飢餓、迫害、そして死の恐怖に脅かされた。そんなある日、シュピルマンとその家族はその他多くのユダヤ人と共に親衛隊の命令で戸外に集められ、財産を取り上げられる。ほどなく彼らは絶滅収容所行きの家畜用列車に乗せられるが、シュピルマンだけは知り合いのユダヤ人ゲットー警察署長ヘラーの機転で救われ、その場を逃れる。ひとり残されたシュピルマンは、移送されずに労働力として残された成人男性たちに混じり、ゲットー内で強制労働を課せられる。ここでシュピルマンは、ドイツがユダヤ人抹殺を計画しているらしいこと、そして生き残ったユダヤ人たちが蜂起の準備をしていることを知る。シュピルマンは慣れない肉体労働やドイツ人警察官から加えられる暴力に耐え切れずに倒れてしまうが、仲間の配慮で倉庫番や食料調達の仕事に回される。シュピルマンは蜂起への協力を志願し、食料調達の立場を利用してゲットーへの武器の持ち込みを手伝う。そんなある日、食料調達のため街(ゲットー外)に出かけたシュピルマンは市場で知人女性ヤニナを見かけ、彼女を頼ってゲットーの外に脱出することを決意する。ゲットーを脱出したシュピルマンは、ヤニナとその夫アンジェイが加わる反ナチス地下活動組織に匿われて、ゲットーのすぐそばの建物の一室に隠れ住む。ほどなくユダヤ人たちのワルシャワ・ゲットー蜂起が起こり、シュピルマンは部屋の窓からドイツ側との激しい交戦を目の当たりにするが、蜂起は鎮圧され、ゲットー内の大半の人が殺される結果に終わる。その後の1年で、ワルシャワの状況は一層悪化する。ヤニナとアンジェイが捕まったため隠れ家でのハンドリング役だったマレクも逃亡し、一人残されたシュピルマンは隣人に存在を気付かれ、隠れ家から逃避しなければならなくなった。マレクから緊急時に見るよう手渡されていたメモに書かれていた住所の家を訪ねると、姿を現したのはドロタだった。シュピルマンはドロタの夫ミルカに匿われ、監視の目の盲点を突くため、ドイツ当局が利用する病院や警察署の向かいにある隠れ家を提供される。しかし連絡員からの食料差し入れが滞り、内臓疾患で死にかけたこともあった。ミルカ一家はドロタの実家がある郊外に避難し、1944年8月、ポーランド人の抵抗勢力はワルシャワ蜂起を起こした。シュピルマンは今回も隠れ家の窓越しに事態の推移を見守るが、この蜂起もまたナチスドイツに鎮圧され、ワルシャワは報復として完膚なきまでの破壊を受ける。砲撃・放火やポーランド人狩りから逃げ惑うシュピルマンは、廃墟と化した都心の中で完全に孤立無援となった。ある日、廃墟の中に立つ一軒家で食べ物をあさっていたシュピルマンは、OGÓRKIの缶詰を発見する。そこへドイツ軍がやって来て、屋根裏部屋に身を隠したシュピルマンは、何者かが弾くピアノソナタの旋律を耳にする。その後ドイツ人たちが立ち去り、夜になって何とか缶を開けようと悪戦苦闘していたシュピルマンは、運転兵だけを伴い再びやって来たドイツ陸軍将校ヴィルム・ホーゼンフェルトと鉢合わせしてしまう。シュピルマンを見つけたホーゼンフェルトは彼の素性を尋ね、彼がユダヤ人ピアニストであることを知るや、1階の居間に残されていたピアノを弾いてみるように促す。生き延びるために、数年間にわたり目の前にピアノがあっても触ることもできなかったシュピルマンだが、彼が弾くショパンのバラード第1番が廃墟の街に流れる。その見事なピアノの腕前に感服し、ドイツの敗退を予想するホーゼンフェルトは、この一軒家に拠点を設けた後、周囲の目を盗んで屋根裏部屋のシュピルマンに食料を差し入れる。包みの中にはライ麦パンとジャムと共に、缶切りが添えられていたのであった。ソ連軍の砲声が迫り、ホーゼンフェルトはシュピルマンにオーバーコートと食料を渡して撤退する。別れ際にシュピルマンの名前(ドイツ語で楽師や演奏家を意味する)を初めて知ったホーゼンフェルトは、ピアニストに相応しいとの言葉を残して去った。しばらくして、拡声器でポーランド国歌を放送する1台のトラックが通り、次いでポーランド軍が現れた。ドイツ将校のコートを着込んだシュピルマンは兵士たちから誤射されるが、同じポーランド人であることが辛うじて伝わり、彼の逃亡生活はようやく終わったのだった。終戦後、シュピルマンは同僚のバイオリニストに案内され、郊外を訪れた。収容所から解放されたバイオリニストが、ソ連軍に捕らえられた一群のドイツ軍将兵とこの場所で遭遇し、その中に「シュピルマンを助けた」と主張する男がいたのだった。しかし監視のソ連兵が割って入ったため、バイオリニストはそのドイツ人の名前を聞き取ることができず、その場所には彼の痕跡を示すものは何も残されていなかった。物語はシュピルマンが演奏する大ポロネーズで締めくくられ、字幕ではホーゼンフェルトが1952年にソ連の強制収容所で死去、そしてシュピルマンが2000年に88歳で死去したことが示される。"
    },
    {
        "title": "キャスト・アウェイ",
        "content": "1995年12月。チャック・ノーランド(トム・ハンクス)はフェデックス倉庫の生産性解決に世界中を飛び回るシステムエンジニアである。彼はテネシー州メンフィス在住のケリー・フレアーズ(ヘレン・ハント)と長年付き合っている。親族と過ごすクリスマスの最中、チャックはマレーシアでのトラブル解決のため呼び出される。ところが悪天候のため、彼の乗った貨物機は太平洋に墜落してしまう。彼は沈みゆく機体からただ一人脱出し、緊急用救命ボートに乗り込み意識を失う。序盤一夜明け気付くと、チャックはある島の海岸に漂着していた。彼が島を探検すると、無人島であることが判明する。墜落機の積荷が何箱も海岸に漂着する。はじめは、救助信号を砂浜に描き、救命ボートの残骸で脱出を試みるが、高波に阻まれ失敗する。食料・水・住処となるべき場所を探し、荷物の箱を開封して使えそうな物を選り分ける。ただ一つ、天使の羽が描かれた箱だけは開けずにおく。火を起こす時に手に負った怪我に怒り、ウイルソン製のバレーボールを投げつける。表面に付いた血痕を利用してボールに顔を描き、ウィルソンと名付け話友達とする。ある夜、自分が見つかるには救助機はテキサス州の2倍の広さを捜索する必要があると判明し、救出の希望を失う。"
    },
    {
        "title": "アルマゲドン",
        "content": "20世紀末、地球軌道上の宇宙空間で人工衛星を修理中のスペースシャトル「アトランティス」との交信が、突然途絶えた。事故直前の映像を解析した結果、流星雨(Meteor shower)がシャトルを直撃し破壊したことが判明した。この流星雨は地球の大気圏を突破して、アメリカ東海岸からフィンランドに至る範囲に降り注ぎ、ニューヨークなどの都市に壊滅的打撃を与えた。さらなる観測と調査によって、これはテキサス州の大きさに匹敵する小惑星が、小惑星帯(Asteroid belt)へ衝突したことに伴う流星雨で、しかも問題の小惑星は地球に向かうコースをとっており、約18日後には地球を直撃し、地球環境に致命的打撃を与えバクテリアすら生き残らない死の惑星へ変えてしまうことも判明する。NASA(アメリカ航空宇宙局)の科学者が言った。「爆竹を、広げた手のひらの上で爆発させてもやけどするだけだ。だが握った手の中で爆発したらどうなるか」。NASAが立案した衝突を回避する唯一の手段は、小惑星の深部まで穴を掘り、内部で核爆弾を炸裂させて真っ二つに割り、軌道を変えるというものだった。この作戦を遂行するために「穴掘りのプロ」――すなわち石油採掘のスペシャリスト達が召集される。それは、大男のベアー、ギャンブル狂のチック、女狂いの天才ロックハウンド、大食漢のマックス、カウボーイ風の地質学者オスカー、ガールフレンドが2人いるフレディ、腕は立つが命令無視が多いA.J.、そして、彼らをまとめるハリーら、石油会社「スタンパー・オイル」の8人の社員たちである。そこに、ウィリアム・シャープ、ジェニファー・ワッツを始めとするNASAのスペースシャトルクルー6人を加えた14人が計画に参加した。NASAの計画は、チタン合金で装甲された新型スペースシャトル「フリーダム」および「インディペンデンス」の2機を打ち上げ、途中でロシア宇宙庁の宇宙ステーションミール(Mir)で燃料である液体酸素を補給、月の軌道で重力アシストをかけ、月の裏側を回ってから加速して、小惑星の後ろから接近するというものである。そのために掘削用車両「アルマジロ」を用意し、ハリーたちはそれらを扱うための辛い訓練を乗り越えた後、チームを半分に分けて新型スペースシャトル2機に分乗し、小惑星へと向かうために飛び立った。地球からの発進こそ無事にできたものの、立ち寄った「ミール」の老朽化のせいで、燃料補給中に燃料漏れを起こして火災が発生、チームは危うく爆発に巻き込まれそうになりつつも、間一髪シャトルで脱出した。「ミール」で単独勤務していたロシア人宇宙飛行士のレヴも一行に加わり、手筈通りに月の軌道を通って小惑星の後ろ側へ回り込み、着陸を試みる2機。ところが、小惑星から放出された大小の岩石が「インディペンデンス」を直撃。同機は操縦不能に陥り、小惑星へ墜落した。乗っていたNASAのクルーや、フレディ、オスカーたちを失うも、A.J.とレヴ、ベアーの3人は生き残り、「アルマジロ」の機銃でシャトルの外壁を打ち破り、ハリーたちの元へと急いだ。途中に深いクレバスがあったが、「アルマジロ」の推進ジェットを使いなんとか越えることができた。一方、一応は着陸に成功した「フリーダム」だったが、そこは当初の予定とは異なる硬い酸化鉄の地盤の上であり、掘削作業は難航した。掘削ドリルも、硬い地盤によって次々に折れ、1本を残し全て破損してしまう。作業の途中、業を煮やしたアメリカ大統領が、作戦に見切りをつけて核爆弾の時限起爆装置を起動させるも、地上にいた良心を持つNASAのスタッフやハリーたちの抵抗[注 1]により地表での爆発を阻止した。最後の1本のドリルを用いて掘削を進める「フリーダム」搭載の「アルマジロ」。しかし、小惑星の地殻変動によるガス噴出で吹き飛ばされ、引火したガスによって操縦席にいたマックス諸共爆発炎上してしまう。「アルマジロ」を失い、万事休すと思われたその時、A.J.たちの乗った「インディペンデンス」搭載の「アルマジロ」が煌々とライトを灯して現われ、掘削作業を再開した。掘削した穴は、どうにか小惑星の計画された深さにまで達し、途中に引っ掛かりながらも核爆弾を押し込んで設置した。後はシャトルが離れてから遠隔操作で起爆させるのみという段階まで来たが、地殻変動によって岩石が降り注ぎ、爆破用リモコンが壊れてしまう。遠隔操作が不可能となったからには、誰かが残って手動で核爆弾を起爆させなければならない。くじ引きの結果、A.J.がその役を担うこととなるも、「フリーダム」のハッチから出る直前、見送りに来たハリーが、A.J.の宇宙服に傷をつけて無理矢理役目を代わり、彼を船内へ戻した。起爆の準備を進めるハリーを尻目に、小惑星からの離陸を試みる「フリーダム」だが、硬着陸や地殻変動の影響によるものかエンジンが起動しなくなっていた。それでも、レヴが「ロシア式の修理」と称してコントロールパネルを叩くと復旧してエンジンが始動し、辛くも離脱に成功。そして、「フリーダム」が小惑星から無事離れたことを確認したハリーは、愛娘グレースに思いを馳せながら起爆スイッチを押す。核爆弾はハリーを巻き込んで爆発した。斯くして、小惑星は大気圏突入前に2つに割れて軌道が変わり、地球滅亡の危機は寸前で回避されるのだった。そして、帰還した乗組員たちは英雄として迎えられた。"
    }
]

# Elasticsearchにドキュメントを登録
try:
    for document in documents:
        res = es.index(index="movies", body=document)
        print(res)
except Exception as e:
    print("An error occurred while indexing the documents:", e)
finally:
    # 内部接続を閉じる
    es.close()

ELASTIC_SEARCH_HOST

ELASTIC_CERT_FINGERPRINT

ELASTIC_PASSWORD には、

“test_connect_elasticsearch.py” 内で定義された変数と同じものを定義してください。

Elasticsearchへデータを新規登録する準備が完了しました!

2. Elasticsearch データ新規登録プログラムを実行しよう

% docker exec -it python bash -c  "python store_elasticsearch.py"

# 実行結果
{'_index': 'movies', '_id': '9JZ-TI4B3cK--OonD8Kg', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 0, '_primary_term': 1}
{'_index': 'movies', '_id': '9ZZ-TI4B3cK--OonD8LV', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 1, '_primary_term': 1}
{'_index': 'movies', '_id': '9pZ-TI4B3cK--OonD8Lb', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 2, '_primary_term': 1}
{'_index': 'movies', '_id': '95Z-TI4B3cK--OonD8Lj', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 3, '_primary_term': 1}
{'_index': 'movies', '_id': '-JZ-TI4B3cK--OonD8Lq', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 4, '_primary_term': 1}
{'_index': 'movies', '_id': '-ZZ-TI4B3cK--OonD8L1', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 5, '_primary_term': 1}
{'_index': 'movies', '_id': '-pZ-TI4B3cK--OonEMIC', '_version': 1, 'result': 'created', '_shards': {'total': 2, 'successful': 1, 'failed': 0}, '_seq_no': 6, '_primary_term': 1}

おめでとうございます!

Elasticsearchのデータ新規登録に成功しました!

3. Elasticsearch データ構造の概念を理解しよう

インデックス(_index)

インデックスは、データを関連付けるための大きなカテゴリやテーマを表すものです。

インデックスは、データの整理や検索を効率的に行うための「フォルダ」や「コンテナ」と考えること

ができます。

今回は、movies インデックスを作成しました。

ドキュメント

ドキュメントは、特定の情報を表す単一のデータエントリです。

例えば、映画タイトル、映画のコンテンツが1つの映画ドキュメントに含まれます。

store_elasticsearch.pyでは、ElasticSearchに新規登録したいドキュメントデータを定義しました。

ドキュメントを一部抜粋
    {
        "title": "ファーザー",
        "content": "アンは80歳になった父親、アンソニーに認知症の兆候が見え始めたのを心配していた。アンソニーにヘルパーを付けようとしたアンだったが、気難しいアンソニーは難癖を付けてはヘルパーを追い出す始末だった。しかし、アンソニーの病状は悪化の一途を辿り、記憶が失われていくだけではなく、自らが置かれた状況すら把握できなくなっていった。困惑するばかりのアンソニーは苛立ちを募らせ、アンに当たることもあった。アンはそんな父親を懸命に支えていたが、気力と体力は消耗するばかりであった。"
    },

ドキュメントID(_id)は、それぞれのドキュメントを一意に識別するための識別子です。

実行結果では、ドキュメントに識別子が割り振られていることを確認できます。

インデックスとドキュメントの関係性

インデックスは複数のドキュメントの「フォルダ」や「コンテナ」として機能し、関連するデータをまとめて管理します。

     +------------------------------------+
     |              インデックス            |
     +------------------------------------+
     |             |             |        |
     |ドキュメント   |ドキュメント   |  ...   |  
     |             |             |        |
     +------------------------------------+

4. Elasticsearch から映画データの全文検索プログラムを作成しよう。

python/src配下に、空のsearch_elasticsearch.pyを新規作成してください。

.
├── elasticsearch
│   └── docker-compose.yml
└── python
    ├── Dockerfile
    ├── docker-compose.yml
    ├── requirements.txt
    └── src
        ├── __init__.py
        ├── test_connect_elasticsearch.py
        ├── store_elasticsearch.py
        └── search_elasticsearch.py

search_elasticsearch.pyに以下コードを貼り付けてください。

import argparse
from elasticsearch import Elasticsearch

ELASTIC_SEARCH_HOST = "192.168.0.18"
ELASTIC_CERT_FINGERPRINT = "B8:80:F2:83:72:C1:EC:0E:2D:B3:21:8A:1F:2C:89:99:97:9D:21:54:D1:5D:7E:2C:AA:97:73:45:28:09:F8:31"
ELASTIC_PASSWORD = "elastic"

# Elasticsearchインスタンスを作成
es = Elasticsearch(    
    f"https://{ELASTIC_SEARCH_HOST}:9200",
    ssl_assert_fingerprint=ELASTIC_CERT_FINGERPRINT,
    basic_auth=("elastic", ELASTIC_PASSWORD),
)

def search_documents(query):
    try:
        # Elasticsearchでドキュメントを検索
        res = es.search(index="movies", body={"query": {"match": {"content": query}}})
        return res
    except Exception as e:
        print("An error occurred while searching:", e)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Search documents in Elasticsearch")
    parser.add_argument("query", type=str, help="Query string to search for")
    args = parser.parse_args()

    search_result = search_documents(args.query)

    # 検索結果を表示
    if search_result:
        print("Search results:")
        for hit in search_result['hits']['hits']:
            print(f"Title: {hit['_source']['title']}")
            print(f"Content: {hit['_source']['content']}")
            print("---")

プログラムは、content 属性に対して検索を行っています。

2. Elasticsearch 全文検索プログラムを実行しよう

第一引数に、全文検索したい文字を入力します。今回は「記憶」で検索します。

% docker exec -it python bash -c  "python search_elasticsearch.py 記憶"

# 実行結果
Search results:
Title: メメント
Content: 『メメント』(英語: Memento)は2000年のアメリカ合衆国の映画。当時未公開のジョナサン・ノーランによる短編小説『Memento Mori(英語版)』の映画化であり、クリストファー・ノーラン脚本・監督によるミステリー、スリラー作品である。妻を殺されそのショックから10分間しか記憶を保てないという記憶障害を抱えることになった主人公レナード・シェルビーが、妻を殺害した犯人を探す過程を描いており、ストーリーを終わりから始まりへ、時系列を逆向きに映し出していく。
---
Title: ファーザー
Content: アンは80歳になった父親、アンソニーに認知症の兆候が見え始めたのを心配していた。アンソニーにヘルパーを付けようとしたアンだったが、気難しいアンソニーは難癖を付けてはヘルパーを追い出す始末だった。しかし、アンソニーの病状は悪化の一途を辿り、記憶が失われていくだけではなく、自らが置かれた状況すら把握できなくなっていった。困惑するばかりのアンソニーは苛立ちを募らせ、アンに当たることもあった。アンはそんな父親を懸命に支えていたが、気力と体力は消耗するばかりであった。
---

Elasticsearchから映画データの全文検索に成功しました!

メメントとファーザーは「記憶」に強く関係する映画です。

今回はここまでになります。次回のテーマも、Elasticsearchを深掘りできたら思います。

k.k
k.k
エンジニア
Webアプリケーション開発の全般(バックエンド、フロントエンド)を担当しています。
特に、バックエンド(Laravel)が得意で、社内メンバーと熱い議論を繰り広げております。
最近は、機械学習に関心があります。
採用情報
お問い合わせ