MongoDB Atlasで全文検索を行う:基礎編 #MongoDB #NoSQL
この記事は1年以上前に投稿されました。情報が古い可能性がありますので、ご注意ください。
Atlasサーチとは
Atlasサーチは、MongoDB Atlasに統合されている日本語を含む多言語の全文検索サービスです。MongoDB Atlas上で提供しており、Elasticsearch、Solrと同じ源泉技術であるApache Luceneをベースにしています。MongoDB Atlasと統合されているために、ユーザは別途のクラスター構成などを意識する必要がありません。そして、検索クエリは、従来のAggregationに全文検索のための$searchステージを提供しており、アプリケーション開発に追加的な負担はありません。ここでは、MongoDB Atlasの全文検索サービスの基本的な使い方などを紹介します。
[関連記事]
Atlasサーチのサービスについて
2020年からサービスを開始し、段階的に機能を拡大しています。
2020年04月、地理情報検索、aggregationの$searchステージのサービス開始
2021年03月、言語アナライザー、トークンフィルター、トークナイザなどを追加。おそらく、本格的な日本語のサポートはここから
最新の状況は、次のURLから参照できます。
www.mongodb.com/docs/atlas/atlas-search/atlas-search-overview
現在、継続的に機能の追加が行われています。
Atlasサーチのアーキテクチャー
Atlasサーチでは、MongoDBクラスターの各ノードに通常のmongodに加えてmongotが配置されます。mongodは通常のMongoDB用のプロセスであり、mongotは全文検索用のプロセスです。
全文検索はmongotで実行し、結果値のObjectIdをmongodに返すと、mongodでビューのための検索を実行し結果を返します。
Atlasのアカウント取得
MongoDB Atlasのアカウントを持ていない方は、MongoDB Atlasのアカウント取得を参照して取得してください。あるいは、本系のURLを利用してください。
特にクレジットカードは不要であり、無料のクラスターが使えます。無料のクラスターは、アカウント取得過程で獲得できます。手順を間違ったなど、クラスターが取得できないかった場合、Atlasのメニューから作成できます(Database→Create)。無料枠のクラスターは、M0タイプを選択してください。
テストデータのアップロード
MongoDB AtlasのUIでサンプルデータをロードできます。
Load Sample Datasetをクリック
サンプルデータの中身は、ここから確認できます。
Atals UIから、組織→プロジェクト→データベース→クラスタのコレクション(Collections)からも、確認できます。
Atlasサーチのためのインデックス作成
Atlasサーチのためのインデックス作成方法は複数あります。
- Atlas UI
- Search API(Curl)
- CLI
ここでは、最も分かりやすいAtlas UIを使って説明します。
1.組織→プロジェクト→データベース→クラスタを選択し、Create Search Indexをクリック
2.Configuration Methodで、Visual Editorを選択し、Nextをクリック
JSON Editorは、様々なオプションに十分に慣れてから、CLIからの実行に向いています。
3.Index名はdefaultでsample_mflex.movies(database.collection)を選択し、Nextをクリック
4.Create Search Indexをクリック
とりあえず、オプションはすべてDefaultで進めてください。
- Index Analyzer:lucene.standard(default)
- Search Analyzer:lucene.standard(default)
- Dynamic Mapping:Enable(default)
- Store Full Document: Disable(default)
Closeで閉じる。
サンプルデータのサイズでは、一分ぐらい掛かります。
Atlasサーチのクエリ実行
ここでは、MongoDB Shell(mongosh)を使っています。
1.MongoDB Shellをインストールしてください
MongoDB ShellはリモートからMongoDB Atlasに接続し、クエリが実行できる最もシンプルなツールです。
MongoDB Toolsのページからお手許のOS環境に合わせてインストールパッケージをダウンロードし、インストールしてください。
2.MongoDB Atlasに接続する
MongoDB Atlas UIから接続文字列を取得してください(組織→プロジェクト→データベース→クラスター→CONNECT→Connect with MongoDB Shell→I have the MongoDB Shell installed)
mongoshからMongoDB Atlasに接続し、moviesデータを1ドキュメント出力してみます。
mongosh "mongodb+srv://<ユーザ>:<パスワード>@cluster0.xxxxx.mongodb.net/test" --apiVersion 1 Current Mongosh Log ID: 6368adbcb3260adc27beadc9 Connecting to: mongodb+srv://@cluster0.xxxxx.mongodb.net/test?appName=mongosh+1.1.9 Using MongoDB: 5.0.13 (API Version 1) Using Mongosh: 1.1.9 For mongosh info see: https://docs.mongodb.com/mongodb-shell/ Atlas Cluster0-shard-0 [primary] test> use sample_mflix switched to db sample_mflix Atlas Cluster0-shard-0 [primary] sample_mflix> show collections comments movies sessions theaters users Atlas Cluster0-shard-0 [primary] sample_mflix> db.movies.findOne() { _id: ObjectId("573a1390f29313caabcd5b9a"), plot: "In the wayward western town known as Hell's Hinges, a local tough guy is reformed by the faith of a good woman.", genres: [ 'Romance', 'Western' ], runtime: 64, rated: 'UNRATED', cast: [ 'William S. Hart', 'Clara Williams', 'Jack Standing', 'Alfred Hollingsworth' ], num_mflix_comments: 2, title: "Hell's Hinges", fullplot: "When Reverend Robert Henley and his sister Faith arrive in the town of Hell's Hinges, saloon owner Silk Miller and his cohorts sense danger to their evil ways. They hire gunman Blaze Tracy to run the minister out of town. But Blaze finds something in Faith Henley that turns him around, and soon Silk Miller and his compadres have Blaze to deal with.", languages: [ 'English' ], released: ISODate("1916-03-05T00:00:00.000Z"), directors: [ 'Charles Swickard', 'William S. Hart', 'Clifford Smith' ], writers: [ 'C. Gardner Sullivan (screenplay)', 'C. Gardner Sullivan (story)' ], awards: { wins: 1, nominations: 0, text: '1 win.' }, lastupdated: '2015-08-16 01:13:00.090000000', year: 1916, imdb: { rating: 6.4, votes: 531, id: 6780 }, countries: [ 'USA' ], type: 'movie', tomatoes: { viewer: { rating: 3.2, numReviews: 98, meter: 36 }, lastUpdated: ISODate("2015-09-01T19:31:17.000Z") } }
<ユーザ>:<パスワード>は、AltasのDafultユーザ(admin)を使うか、別途作成してください(組織→プロジェクト→Database Access→ADD NEW DATABASE USER)
3.クエリを実行する
クエリは、集計クエリ(Aggregation)の全文検索のステージ($search)を利用します。
db.movies.aggregate([ { $search: { "index": "default", "text": { "query": "baseball", "path": "plot" } } }, { $limit:5 }, { $project: { "_id": 0, "title": 1, "plot": 1 } } ]) [ { plot: 'A trio of guys try and make up for missed opportunities in childhood by forming a three-player baseball team to compete against standard children baseball squads.', title: 'The Benchwarmers' }, { plot: 'A young boy is bequeathed the ownership of a professional baseball team.', title: 'Little Big League' }, { plot: 'A trained chimpanzee plays third base for a minor-league baseball team.', title: 'Ed' }, { plot: 'The story of the life and career of the famed baseball player, Lou Gehrig.', title: 'The Pride of the Yankees' }, { plot: 'Babe Ruth becomes a baseball legend but is unheroic to those who know him.', title: 'The Babe' } ]
このクエリは、plotというフィルドへbaseballという文字列が入っているドキュメントを検索し、5行まで表示するというクエリです。
$search | aggregationで全文検索を示すステージ |
---|---|
index | default インデックス名がdefaultの場合は、省略可能 |
text | サーチ対象がテキスト/数字/日付 |
query | baseball 検索対象の文字列 |
path | plot 検索対象のフィルド名 |
$limit | 5 表示するドキュメント数 |
$project | 表示するという意味であり、ファイル名に対して"1"は表示する、"0"は表示しない |
もう一つのクエリを見てみます。
db.movies.aggregate([ { $search: { "index": "default", "compound": { "must": [ { "text": { "query": ["Hawaii", "Alaska"], "path": "plot" }, }, { "regex": { "query": "([0-9]{4})", "path": "plot", "allowAnalyzedField": true } } ], "mustNot": [ { "text": { "query": ["Comedy", "Romance"], "path": "genres" } }, { "text": { "query": ["Beach", "Snow"], "path": "title" } } ] } } }, { $project: { "title": 1, "plot": 1, "genres": 1, "_id": 0 } } ]) [ { plot: 'A modern aircraft carrier is thrown back in time to 1941 near Hawaii, just hours before the Japanese attack on Pearl Harbor.', genres: [ 'Action', 'Sci-Fi' ], title: 'The Final Countdown' }, { plot: "Follows John McCain's 2008 presidential campaign, from his selection of Alaska Governor Sarah Palin as his running mate to their ultimate defeat in the general election.", genres: [ 'Biography', 'Drama', 'History' ], title: 'Game Change' }, { plot: 'A devastating and heartrending take on grizzly bear activists Timothy Treadwell and Amie Huguenard, who were killed in October of 2003 while living among grizzlies in Alaska.', genres: [ 'Documentary', 'Biography' ], title: 'Grizzly Man' }, { plot: 'Truman Korovin is a lonely, sharp-witted cab driver in Fairbanks, Alaska, 1980. The usual routine of picking up fares and spending his nights at his favorite bar, the Boatel, is disrupted ...', genres: [ 'Drama' ], title: 'Chronic Town' } ]
このクエリは、plotフィルドへ ["Hawaii", "Alaska"]の文字列が必ず存在すること及びplotフィルドへ年度らしきデータが存在すること(連続する4桁の数字)。
同時にgenresフィルドへ["Comedy", "Romance"]が含まれていない及び"title"フィルドへ ["Beach", "Snow"]も含まれていないドキュメントを検索し、title、plot、genresを表示するというクエリです。
$search | aggregationで全文検索を示すステージ |
---|---|
index | default インデックス名がdefaultの場合は省略可能 |
compound | 複数の条件であること |
must | 必ず条件を満たすこと |
text | サーチ対象がテキスト/数字/日付 |
query | ["Hawaii", "Alaska"] 検索対象の文字列 |
path | plot 検索対象のフィルド名 |
regex | 正規式である |
query | ([0-9]{4}) 0-9までの数字が4桁並んでいること |
path | plot 検索対象のフィルド名 |
allowAnalyzedField | True ワイルドカードを使うということ |
mustNot | 同時にgenresフィルドへ["Comedy", "Romance"]は含まれていない。"title"フィルドへ ["Beach", "Snow"]も含まれていない |
$project | 表示するという意味であり、ファイル名に対して"1"は表示する、"0"は表示しない |
まとめ
今回は、英語をベースにAtlasサーチの基本的な使い方を紹介しました。これから数回に渡って使い方などを連載していきます。
[参照]
www.mongodb.com/docs/atlas/atlas-search