跳至主要内容

MongoDB

MongoDB 引擎是一个只读表引擎,允许从远程 MongoDB 集合读取数据。

仅支持 MongoDB v3.6+ 服务器。 种子列表 (mongodb+srv) 尚未支持。

注意

如果您遇到问题,请报告问题,并尝试使用 旧版实现。请记住,它已弃用,将在下一个版本中删除。

创建表

CREATE TABLE [IF NOT EXISTS] [db.]table_name
(
name1 [type1],
name2 [type2],
...
) ENGINE = MongoDB(host:port, database, collection, user, password [, options]);

引擎参数

  • host:port — MongoDB 服务器地址。

  • database — 远程数据库名称。

  • collection — 远程集合名称。

  • user — MongoDB 用户。

  • password — 用户密码。

  • options — MongoDB 连接字符串选项(可选参数)。

提示

如果您使用的是 MongoDB Atlas 云服务,则可以在“Atlas SQL”选项中获取连接 URL。种子列表 (mongodb**+srv**) 尚未支持,但将在未来版本中添加。

此外,您可以简单地传递一个 URI

ENGINE = MongoDB(uri, collection);

引擎参数

  • uri — MongoDB 服务器的连接 URI

  • collection — 远程集合名称。

类型映射

MongoDBClickHouse
bool, int32, int64任何数值类型, String
doubleFloat64, String
dateDate, Date32, DateTime, DateTime64, String
stringString, UUID
documentString(作为 JSON)
arrayArray, String(作为 JSON)
oidString
binary如果在列中,则为 String,如果在数组或文档中,则为 base64 编码的字符串
任何其他String

如果在 MongoDB 文档中未找到键(例如,列名不匹配),则会插入默认值或 NULL(如果该列是可空的)。

支持的子句

仅支持具有简单表达式的查询(例如,WHERE field = <constant> ORDER BY field2 LIMIT <constant>)。这些表达式将转换为 MongoDB 查询语言,并在服务器端执行。您可以使用 mongodb_throw_on_unsupported_query 禁用所有这些限制。在这种情况下,ClickHouse 会尽力尝试转换查询,但这会导致全表扫描和 ClickHouse 侧面的处理。

注意

最好显式设置文字类型,因为 Mongo 需要严格类型的过滤器。例如,您要按 Date 过滤

SELECT * FROM mongo_table WHERE date = '2024-01-01'

这将无法正常工作,因为 Mongo 不会将字符串转换为 Date,因此您需要手动转换它

SELECT * FROM mongo_table WHERE date = '2024-01-01'::Date OR date = toDate('2024-01-01')

这适用于 DateDate32DateTimeBoolUUID

使用示例

假设 MongoDB 已加载 sample_mflix 数据集

在 ClickHouse 中创建一个表,允许从 MongoDB 集合读取数据

CREATE TABLE sample_mflix_table
(
_id String,
title String,
plot String,
genres Array(String),
directors Array(String),
writers Array(String),
released Date,
imdb String,
year String,
) ENGINE = MongoDB('mongodb://<USERNAME>:<PASSWORD>@atlas-sql-6634be87cefd3876070caf96-98lxs.a.query.mongodb.net/sample_mflix?ssl=true&authSource=admin', 'movies');

查询

SELECT count() FROM sample_mflix_table
   ┌─count()─┐
1. │ 21349 │
└─────────┘
-- JSONExtractString cannot be pushed down to MongoDB
SET mongodb_throw_on_unsupported_query = 0;

-- Find all 'Back to the Future' sequels with rating > 7.5
SELECT title, plot, genres, directors, released FROM sample_mflix_table
WHERE title IN ('Back to the Future', 'Back to the Future Part II', 'Back to the Future Part III')
AND toFloat32(JSONExtractString(imdb, 'rating')) > 7.5
ORDER BY year
FORMAT Vertical;
Row 1:
──────
title: Back to the Future
plot: A young man is accidentally sent 30 years into the past in a time-traveling DeLorean invented by his friend, Dr. Emmett Brown, and must make sure his high-school-age parents unite in order to save his own existence.
genres: ['Adventure','Comedy','Sci-Fi']
directors: ['Robert Zemeckis']
released: 1985-07-03

Row 2:
──────
title: Back to the Future Part II
plot: After visiting 2015, Marty McFly must repeat his visit to 1955 to prevent disastrous changes to 1985... without interfering with his first trip.
genres: ['Action','Adventure','Comedy']
directors: ['Robert Zemeckis']
released: 1989-11-22
-- Find top 3 movies based on Cormac McCarthy's books
SELECT title, toFloat32(JSONExtractString(imdb, 'rating')) as rating
FROM sample_mflix_table
WHERE arrayExists(x -> x like 'Cormac McCarthy%', writers)
ORDER BY rating DESC
LIMIT 3;
   ┌─title──────────────────┬─rating─┐
1. │ No Country for Old Men │ 8.1 │
2. │ The Sunset Limited │ 7.4 │
3. │ The Road │ 7.3 │
└────────────────────────┴────────┘

故障排除

您可以在 DEBUG 级别的日志中查看生成的 MongoDB 查询。

实现细节可以在 mongocxxmongoc 文档中找到。