PostgreSQLの外部データラッパー(FDW)でMongoDBにアクセス

はじめに

PostgreSQLには外部データラッパー(以降、FDW)と呼ばれる拡張機能があります。この拡張を使うとPostgreSQLから外部のデータソース*1に接続することができます。

本エントリでは、このFDWを用いてMongoDBのドキュメントをPostgreSQL上で扱う方法を説明します。

f:id:hiroki-sawano:20200804205803p:plain

MongoDBサーバ

まずはPostgreSQLから接続するMongoDBを用意します。
使用するバージョンは v4.0.8 です。

# mongo --version
MongoDB shell version v4.0.8

テストデータの用意

PostgreSQLから取得するデータを用意します。
適当に mydb データベースの mycollection コレクションに3つのドキュメントを登録しておきます。

> use mydb
> db.mycollection.insert({ foo: "1", bar: "2", foobar: "3"})
> db.mycollection.insert({ foo: "4", bar: "5", foobar: "6"})
> db.mycollection.insert({ foo: "7", bar: "8", foobar: "9"})
> db.mycollection.find().pretty()
{
    "_id" : ObjectId("5f2941a85ee8845a53018f66"),
    "foo" : "1",
    "bar" : "2",
    "foobar" : "3"
}
{
    "_id" : ObjectId("5f2941b95ee8845a53018f67"),
    "foo" : "4",
    "bar" : "5",
    "foobar" : "6"
}
{
    "_id" : ObjectId("5f2941c45ee8845a53018f68"),
    "foo" : "7",
    "bar" : "8",
    "foobar" : "9"
}
> 

PostgreSQLサーバ

PostgreSQLはバージョン9.6を使います。FDWが実装されている9.1以降であれば問題ないと思います。

$ psql --version
psql (PostgreSQL) 9.6.18

FDWのインストールでPython2系が必要になるので、Python2.7をインストールしておきます(インストール手順は省略)。

$ python --version
Python 2.7.5

Multicornのインストール

後述のFDWはMulticornで実装されているのでインストールします。
バージョンは動作確認した v1.4.0 を指定しています。

$ git clone git://github.com/Kozea/Multicorn.git -b v1.4.0
$ cd Multicorn
$ make && make install

yam_fdwのインストール

MongoDB用のFDWであるyam_fdwをインストールします。

$ git clone https://github.com/asya999/yam_fdw.git
$ cd yam_fdw
$ python setup.py install

外部テーブルの作成

以下のSQLで適当なデータベースを作成し、FDWを利用するための準備をします。

CREATE DATABASE mydb;
\c mydb
CREATE EXTENSION multicorn;
CREATE SERVER mongodb_mydb_server FOREIGN DATA WRAPPER multicorn OPTIONS (
  wrapper 'yam_fdw.Yamfdw'
);

続けて、MongoDBで作成したおいた mycollection に対応するテーブルを作成します。
_id 列は必須です。その他の列は参照したい項目を適切なデータ型で定義します。
userpassword にはMongoDBへの接続で認証に使用するユーザ情報を指定してください(認証なしの場合は省略)。

CREATE FOREIGN TABLE mycollection (
  "_id" VARCHAR NOT NULL,
  "foo" VARCHAR NOT NULL,
  "bar" VARCHAR,
  "foobar" INTEGER
) SERVER mongodb_mydb_server OPTIONS (
  host '<mongodb-host>',
  port '27017',
  db 'mydb',
  user '<username>',
  password '<password>',
  collection 'mycollection'
);

これで外部テーブル mycollection ができました。

# \d mycollection

         Foreign table "public.mycollection"
 Column |       Type        | Modifiers | FDW Options 
--------+-------------------+-----------+-------------
 _id    | character varying | not null  | 
 foo    | character varying | not null  | 
 bar    | character varying |           | 
 foobar | integer           |           | 
Server: mongodb_mydb_server
FDW Options: (host '...', port '27017', db 'mydb', collection 'mycollection')

MongoDBにアクセス

実際にSQLmycollection テーブルに対して実行すると、 以下のようにMongoDBに事前登録した mycollection のデータ3件を取得できます。

# SELECT * FROM mycollection;

           _id            | foo | bar | foobar 
--------------------------+-----+-----+--------
 5f2941a85ee8845a53018f66 | 1   | 2   |      3
 5f2941b95ee8845a53018f67 | 4   | 5   |      6
 5f2941c45ee8845a53018f68 | 7   | 8   |      9
(3 rows)