fbpx

CL LAB

HOME > Blog > MongoDB Atlas 全文検索サービス:基礎編 #MongoDB #NoSQL

MongoDB Atlas 全文検索サービス:基礎編 #MongoDB #NoSQL

 ★ 0

Atlasサーチとは

MongoDB Atlas上で日本語を含む多言語の全文検索が可能になりました。従来では日本語対応ができておらず、商品説明など自然文からインデックスを作成し、曖昧検索や類似語検索などを行うことはできませんでした。筆頭データベースとしてMongoDBを使っていながらも、Elasticsearch又はSolr上に構築するか、あるいは全文検索の要件が含まれると、MongoDB自体が敬遠されるようなことも起きていました。しかし、もう、大丈夫です。Atlasサーチは部分的に全文検索の要件が含まれるようなケースでは確かな選択であると言えます。本格的な全文検索エンジンとして使えるかどうかは、また、機能を拡充している途上であり、要件と機能間のフィット&ギャップの分析が必要かと思います。

  • MongoDB Atlas上で提供します(クラウドのみ)
  • Elasticsearch、Solrと同じ源泉技術である[Apache Lucene](https://lucene.apache.org/)をベースにしています
  • MongoDB Atlasと統合されており、ユーザは別途の構成などを意識する必要はありません
  • アプリケーション開発に追加的な負担はありません

ここでは、MongoDB Atlasの全文検索サービスの基本的な使い方を簡略に紹介させて頂きます。

[参照]
www.mongodb.com/docs/atlas/atlas-search

Atlasサーチのサービスについて

2020年からサービスを開始し、段階的に機能を拡大しています。
2020年04月、地理情報検索、aggregationの$searchステージのサービス開始
2021年03月、言語アナライザー、トークンフィルター、トークナイザなどを追加。おそらく、本格的な日本語のサポートはここから

最新の状況は、次から参照できます。
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を利用してください。

www.mongodb.com/atlas/database

特にクレジットカードは不要であり、無料のクラスターが使えます。無料のクラスターは、アカウント取得過程で獲得できます。手順を間違ったなど、クラスターが取得できないかった場合、Atlasのメニューから作成できます(Database→Create)。無料枠のクラスターは、M0タイプを選択してください。

テストデータのアップロード

MongoDB AtlasのUIでサンプルデータをロードできます。

Load Sample Datasetをクリック

サンプルデータの中身は、ここから確認できます。
www.mongodb.com/docs/atlas/sample-data

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のページからお手許の環境に合わせてインストールしてください。
www.mongodb.com/try/download/shell

ここでは、Windows環境なのでmongosh-1.6.0-x64.msiをダウンロードし、インストールしています。

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サーチの基本的な使い方について紹介しました。ごれから数回に渡って多様なオプションなどを紹介していきます。もちろん、日本語の全文検索の紹介も予定しています。

Author

データベースが大好きなサーバサイドのエンジニア。現代的なデータ基盤のソリューションアーキテクトとして活動しています。

[著書]
グラフデータベースNeo4jの他
https://www.amazon.co.jp/李昌桓/e/B004LWEKOU

leeの記事一覧

CL LAB Mail Magazine

CL LABの情報を逃さずチェックしよう!

メールアドレスを登録すると記事が投稿されるとメールで通知します。

メールアドレス: 登録

※登録後メールに記載しているリンクをクリックして認証してください。

Related post

[無料ウェビナー] GitLab_CI/CDハンズオン_2023111